VertexProgram.cpp revision 53ad4afcee973b4323f84eb54c26d8329c66e51c
10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
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
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
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.
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "VertexProgram.hpp"
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "VertexShader.hpp"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SamplerCore.hpp"
19708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Renderer/Renderer.hpp"
20708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Renderer/Vertex.hpp"
21708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Common/Half.hpp"
22708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Common/Debug.hpp"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace sw
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{
267551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens	VertexProgram::VertexProgram(const VertexProcessor::State &state, const VertexShader *shader)
277551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		: VertexRoutine(state, shader), shader(shader), r(shader->dynamicallyIndexedTemporaries)
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth = 0;
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth = 0;
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		breakDepth = 0;
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		currentLabel = -1;
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		whileTest = false;
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		for(int i = 0; i < 2048; i++)
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[i] = 0;
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
397551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
407551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth = -1;
417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
437551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		if(shader && shader->containsBreakInstruction())
447551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		{
457551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		}
477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		if(shader && shader->containsContinueInstruction())
497551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		{
507551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
517551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		}
527551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
5302ad0aa756ab6cbfb6ca00b98ac6793536ff9820Alexis Hetu		if(shader->isInstanceIdDeclared())
547551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		{
557551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			instanceID = *Pointer<Int>(data + OFFSET(DrawData,instanceID));
567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		}
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	VertexProgram::~VertexProgram()
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
63877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu	void VertexProgram::pipeline(UInt& index)
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!state.preTransformed)
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
67877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			program(index);
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
71b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			passThrough();
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
75877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu	void VertexProgram::program(UInt& index)
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	//	shader->print("VertexShader-%0.8X.txt", state.shaderID);
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
7953ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu		unsigned short shaderModel = shader->getShaderModel();
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
817551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex = 0;
827551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		stackIndex = 0;
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
844677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens		if(shader->containsLeaveInstruction())
854677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens		{
867551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
874677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens		}
884677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens
89877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu		if(shader->isVertexIdDeclared())
90877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu		{
91877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			if(state.textureSampling)
92877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
93877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Int4(index);
94877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
95877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			else
96877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
97877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index), 0);
98877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index + 1), 1);
99877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index + 2), 2);
100877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index + 3), 3);
101877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
102877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu		}
103877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// Create all call site return blocks up front
105903e025f6cd8d978f013c741431b87b04ae01fd1Alexis Hetu		for(size_t i = 0; i < shader->getLength(); i++)
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			const Shader::Instruction *instruction = shader->getInstruction(i);
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Shader::Opcode opcode = instruction->opcode;
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(opcode == Shader::OPCODE_CALL || opcode == Shader::OPCODE_CALLNZ)
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				const Dst &dst = instruction->dst;
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				ASSERT(callRetBlock[dst.label].size() == dst.callSite);
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				callRetBlock[dst.label].push_back(Nucleus::createBasicBlock());
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
118b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
119903e025f6cd8d978f013c741431b87b04ae01fd1Alexis Hetu		for(size_t i = 0; i < shader->getLength(); i++)
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			const Shader::Instruction *instruction = shader->getInstruction(i);
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Shader::Opcode opcode = instruction->opcode;
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(opcode == Shader::OPCODE_DCL || opcode == Shader::OPCODE_DEF || opcode == Shader::OPCODE_DEFI || opcode == Shader::OPCODE_DEFB)
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				continue;
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Dst dst = instruction->dst;
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Src src0 = instruction->src[0];
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Src src1 = instruction->src[1];
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Src src2 = instruction->src[2];
133c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			Src src3 = instruction->src[3];
13425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu			Src src4 = instruction->src[4];
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			bool predicate = instruction->predicate;
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Control control = instruction->control;
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			bool integer = dst.type == Shader::PARAMETER_ADDR;
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			bool pp = dst.partialPrecision;
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f d;
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f s0;
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f s1;
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f s2;
145c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			Vector4f s3;
14625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu			Vector4f s4;
147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
148c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0);
149c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1);
150c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2);
151c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegister(src3);
152c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegister(src4);
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			switch(opcode)
155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
156b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_1_0:                                     break;
157b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_1_1:                                     break;
158b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_2_0:                                     break;
159b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_2_x:                                     break;
160b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_2_sw:                                    break;
161b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_3_0:                                     break;
162b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_3_sw:                                    break;
163b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DCL:                                        break;
164b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DEF:                                        break;
165b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DEFI:                                       break;
166b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DEFB:                                       break;
167b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NOP:                                        break;
168b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ABS:        abs(d, s0);                     break;
1690f4480780a2bfad69cece5fd9cabd1bf89f7393eAlexis Hetu			case Shader::OPCODE_IABS:       iabs(d, s0);                    break;
170b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ADD:        add(d, s0, s1);                 break;
1718d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IADD:       iadd(d, s0, s1);                break;
172b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CRS:        crs(d, s0, s1);                 break;
173b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD1:   forward1(d, s0, s1, s2);        break;
174b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD2:   forward2(d, s0, s1, s2);        break;
175b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD3:   forward3(d, s0, s1, s2);        break;
176b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD4:   forward4(d, s0, s1, s2);        break;
177b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT1:   reflect1(d, s0, s1);            break;
178b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT2:   reflect2(d, s0, s1);            break;
179b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT3:   reflect3(d, s0, s1);            break;
180b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT4:   reflect4(d, s0, s1);            break;
181b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT1:   refract1(d, s0, s1, s2.x);      break;
182b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT2:   refract2(d, s0, s1, s2.x);      break;
183b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT3:   refract3(d, s0, s1, s2.x);      break;
184b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT4:   refract4(d, s0, s1, s2.x);      break;
185b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP1:        dp1(d, s0, s1);                 break;
186b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP2:        dp2(d, s0, s1);                 break;
187b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP3:        dp3(d, s0, s1);                 break;
188b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP4:        dp4(d, s0, s1);                 break;
189c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET2:       det2(d, s0, s1);                break;
190c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET3:       det3(d, s0, s1, s2);            break;
191c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET4:       det4(d, s0, s1, s2, s3);        break;
192b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATT:        att(d, s0, s1);                 break;
193b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXP2X:      exp2x(d, s0, pp);               break;
194b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXP2:       exp2(d, s0, pp);                break;
19553ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu			case Shader::OPCODE_EXPP:       expp(d, s0, shaderModel);       break;
196b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXP:        exp(d, s0, pp);                 break;
197b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FRC:        frc(d, s0);                     break;
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			case Shader::OPCODE_TRUNC:      trunc(d, s0);                   break;
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			case Shader::OPCODE_FLOOR:      floor(d, s0);                   break;
200af1970ce7685ea66dd02ac462d6f2723d6f6e500Alexis Hetu			case Shader::OPCODE_ROUND:      round(d, s0);                   break;
201b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ROUNDEVEN:  roundEven(d, s0);               break;
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			case Shader::OPCODE_CEIL:       ceil(d, s0);                    break;
203b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LIT:        lit(d, s0);                     break;
204b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOG2X:      log2x(d, s0, pp);               break;
205b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOG2:       log2(d, s0, pp);                break;
20653ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu			case Shader::OPCODE_LOGP:       logp(d, s0, shaderModel);       break;
207b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOG:        log(d, s0, pp);                 break;
208b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LRP:        lrp(d, s0, s1, s2);             break;
209b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_STEP:       step(d, s0, s1);                break;
210b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SMOOTH:     smooth(d, s0, s1, s2);          break;
2118ef6d1097d9fe71a2461a5040bddb1893bdbed6cAlexis Hetu			case Shader::OPCODE_ISINF:      isinf(d, s0);                   break;
2128ef6d1097d9fe71a2461a5040bddb1893bdbed6cAlexis Hetu			case Shader::OPCODE_ISNAN:      isnan(d, s0);                   break;
2138d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_FLOATBITSTOINT:
2148d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_FLOATBITSTOUINT:
2158d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_INTBITSTOFLOAT:
2168d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UINTBITSTOFLOAT: d = s0;                    break;
2179cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_PACKSNORM2x16:   packSnorm2x16(d, s0);      break;
2189cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_PACKUNORM2x16:   packUnorm2x16(d, s0);      break;
219ffb35eb4ab1b99c9bb6583c39211386fa577ef02Alexis Hetu			case Shader::OPCODE_PACKHALF2x16:    packHalf2x16(d, s0);       break;
2209cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_UNPACKSNORM2x16: unpackSnorm2x16(d, s0);    break;
2219cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_UNPACKUNORM2x16: unpackUnorm2x16(d, s0);    break;
222ffb35eb4ab1b99c9bb6583c39211386fa577ef02Alexis Hetu			case Shader::OPCODE_UNPACKHALF2x16:  unpackHalf2x16(d, s0);     break;
223b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M3X2:       M3X2(d, s0, src1);              break;
224b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M3X3:       M3X3(d, s0, src1);              break;
225b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M3X4:       M3X4(d, s0, src1);              break;
226b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M4X3:       M4X3(d, s0, src1);              break;
227b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M4X4:       M4X4(d, s0, src1);              break;
228b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MAD:        mad(d, s0, s1, s2);             break;
229b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_IMAD:       imad(d, s0, s1, s2);            break;
230b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MAX:        max(d, s0, s1);                 break;
2318d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMAX:       imax(d, s0, s1);                break;
2328d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMAX:       umax(d, s0, s1);                break;
233b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MIN:        min(d, s0, s1);                 break;
2348d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMIN:       imin(d, s0, s1);                break;
2358d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMIN:       umin(d, s0, s1);                break;
236b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MOV:        mov(d, s0, integer);            break;
23702a2bb807c1e947bc99d68ba7dd4984289278be0Alexis Hetu			case Shader::OPCODE_MOVA:       mov(d, s0, true);               break;
2388d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_NEG:        neg(d, s0);                     break;
2398d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_INEG:       ineg(d, s0);                    break;
240b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_F2B:        f2b(d, s0);                     break;
241b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_B2F:        b2f(d, s0);                     break;
2428d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_F2I:        f2i(d, s0);                     break;
2438d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_I2F:        i2f(d, s0);                     break;
2448d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_F2U:        f2u(d, s0);                     break;
2458d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_U2F:        u2f(d, s0);                     break;
2468d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_I2B:        i2b(d, s0);                     break;
2478d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_B2I:        b2i(d, s0);                     break;
248b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MUL:        mul(d, s0, s1);                 break;
2498d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMUL:       imul(d, s0, s1);                break;
250b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NRM2:       nrm2(d, s0, pp);                break;
251b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NRM3:       nrm3(d, s0, pp);                break;
252b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NRM4:       nrm4(d, s0, pp);                break;
253b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_POWX:       powx(d, s0, s1, pp);            break;
254b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_POW:        pow(d, s0, s1, pp);             break;
255b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RCPX:       rcpx(d, s0, pp);                break;
256b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIV:        div(d, s0, s1);                 break;
2578d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IDIV:       idiv(d, s0, s1);                break;
2588d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UDIV:       udiv(d, s0, s1);                break;
259b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MOD:        mod(d, s0, s1);                 break;
2608d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMOD:       imod(d, s0, s1);                break;
2618d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMOD:       umod(d, s0, s1);                break;
2628d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_SHL:        shl(d, s0, s1);                 break;
263b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ISHR:       ishr(d, s0, s1);                break;
264b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_USHR:       ushr(d, s0, s1);                break;
265b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RSQX:       rsqx(d, s0, pp);                break;
266b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SQRT:       sqrt(d, s0, pp);                break;
267b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RSQ:        rsq(d, s0, pp);                 break;
268b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEN2:       len2(d.x, s0, pp);              break;
269b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEN3:       len3(d.x, s0, pp);              break;
270b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEN4:       len4(d.x, s0, pp);              break;
271b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST1:      dist1(d.x, s0, s1, pp);         break;
272b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST2:      dist2(d.x, s0, s1, pp);         break;
273b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST3:      dist3(d.x, s0, s1, pp);         break;
274b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST4:      dist4(d.x, s0, s1, pp);         break;
275b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SGE:        step(d, s1, s0);                break;
276b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SGN:        sgn(d, s0);                     break;
2770f4480780a2bfad69cece5fd9cabd1bf89f7393eAlexis Hetu			case Shader::OPCODE_ISGN:       isgn(d, s0);                    break;
278b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SINCOS:     sincos(d, s0, pp);              break;
279b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_COS:        cos(d, s0, pp);                 break;
280b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SIN:        sin(d, s0, pp);                 break;
281b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TAN:        tan(d, s0);                     break;
282b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ACOS:       acos(d, s0);                    break;
283b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ASIN:       asin(d, s0);                    break;
284b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATAN:       atan(d, s0);                    break;
285b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATAN2:      atan2(d, s0, s1);               break;
286b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_COSH:       cosh(d, s0, pp);                break;
287b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SINH:       sinh(d, s0, pp);                break;
288b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TANH:       tanh(d, s0, pp);                break;
289b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ACOSH:      acosh(d, s0, pp);               break;
290b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ASINH:      asinh(d, s0, pp);               break;
291b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATANH:      atanh(d, s0, pp);               break;
292b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SLT:        slt(d, s0, s1);                 break;
293b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SUB:        sub(d, s0, s1);                 break;
2948d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_ISUB:       isub(d, s0, s1);                break;
295b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_BREAK:      BREAK();                        break;
296b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_BREAKC:     BREAKC(s0, s1, control);        break;
297b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_BREAKP:     BREAKP(src0);                   break;
298b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CONTINUE:   CONTINUE();                     break;
299b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEST:       TEST();                         break;
300b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CALL:       CALL(dst.label, dst.callSite);  break;
301b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CALLNZ:     CALLNZ(dst.label, dst.callSite, src0); break;
302b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ELSE:       ELSE();                         break;
303b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDIF:      ENDIF();                        break;
304b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDLOOP:    ENDLOOP();                      break;
305b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDREP:     ENDREP();                       break;
306b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDWHILE:   ENDWHILE();                     break;
3079aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu			case Shader::OPCODE_ENDSWITCH:  ENDSWITCH();                    break;
308b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_IF:         IF(src0);                       break;
309b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_IFC:        IFC(s0, s1, control);           break;
310b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LABEL:      LABEL(dst.index);               break;
311b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOOP:       LOOP(src1);                     break;
312b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REP:        REP(src0);                      break;
313b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_WHILE:      WHILE(src0);                    break;
3149aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu			case Shader::OPCODE_SWITCH:     SWITCH();                       break;
315b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RET:        RET();                          break;
316b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEAVE:      LEAVE();                        break;
317b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CMP:        cmp(d, s0, s1, control);        break;
318b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ICMP:       icmp(d, s0, s1, control);       break;
3198d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UCMP:       ucmp(d, s0, s1, control);       break;
320b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SELECT:     select(d, s0, s1, s2);          break;
321b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXTRACT:    extract(d.x, s0, s1.x);         break;
322b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_INSERT:     insert(d, s0, s1.x, s2.x);      break;
323b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ALL:        all(d.x, s0);                   break;
324b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ANY:        any(d.x, s0);                   break;
32524f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_NOT:        bitwise_not(d, s0);             break;
32624f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_OR:         bitwise_or(d, s0, s1);          break;
32724f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_XOR:        bitwise_xor(d, s0, s1);         break;
32824f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_AND:        bitwise_and(d, s0, s1);         break;
3298d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_EQ:         equal(d, s0, s1);               break;
3308d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_NE:         notEqual(d, s0, s1);            break;
331a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLDL:     TEXLOD(d, s0, src1, s0.w);      break;
332a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLOD:     TEXLOD(d, s0, src1, s2.x);      break;
333b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEX:        TEX(d, s0, src1);               break;
3342337a192aa163b1076ba768e414c5fe27f1a9143Meng-Lin Wu			case Shader::OPCODE_TEXOFFSET:  TEXOFFSET(d, s0, src1, s2);     break;
335a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x); break;
336a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x);  break;
337a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
338b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEXGRAD:    TEXGRAD(d, s0, src1, s2, s3);   break;
339a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
340b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEXSIZE:    TEXSIZE(d, s0.x, src1);         break;
341b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_END:                                        break;
342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			default:
343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				ASSERT(false);
344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(dst.type != Shader::PARAMETER_VOID && dst.type != Shader::PARAMETER_LABEL && opcode != Shader::OPCODE_NOP)
347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				if(dst.saturate)
349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = Max(d.x, Float4(0.0f));
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = Max(d.y, Float4(0.0f));
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = Max(d.z, Float4(0.0f));
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = Max(d.w, Float4(0.0f));
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = Min(d.x, Float4(1.0f));
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = Min(d.y, Float4(1.0f));
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = Min(d.z, Float4(1.0f));
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = Min(d.w, Float4(1.0f));
359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
361c6e8ab13ecf20217229de8f4f19a14bbc18778f9Nicolas Capens				if(instruction->isPredicated())
362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					Vector4f pDst;   // FIXME: Rename
364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					switch(dst.type)
366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
367b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens					case Shader::PARAMETER_VOID: break;
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_TEMP:
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(dst.rel.type == Shader::PARAMETER_VOID)
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
3717551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = r[dst.index].x;
3727551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = r[dst.index].y;
3737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = r[dst.index].z;
3747551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = r[dst.index].w;
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						}
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						else
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
378b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens							Int a = relativeAddress(dst);
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3807551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = r[dst.index + a].x;
3817551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = r[dst.index + a].y;
3827551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = r[dst.index + a].z;
3837551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = r[dst.index + a].w;
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						}
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						break;
3867551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_ADDR: pDst = a0; break;
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_RASTOUT:
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						switch(dst.index)
389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						case 0:
3917551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = o[Pos].x;
3927551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = o[Pos].y;
3937551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = o[Pos].z;
3947551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = o[Pos].w;
395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							break;
396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						case 1:
3977551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							pDst.x = o[Fog].x;
398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							break;
399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						case 2:
4007551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							pDst.x = o[Pts].y;
401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							break;
402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						default:
403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							ASSERT(false);
404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_ATTROUT:
407995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.x) pDst.x = o[C0 + dst.index].x;
408995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.y) pDst.y = o[C0 + dst.index].y;
409995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.z) pDst.z = o[C0 + dst.index].z;
410995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.w) pDst.w = o[C0 + dst.index].w;
411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_TEXCRDOUT:
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				//	case Shader::PARAMETER_OUTPUT:
41453ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu						if(shaderModel < 0x0300)
415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
4167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = o[T0 + dst.index].x;
4177551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = o[T0 + dst.index].y;
4187551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = o[T0 + dst.index].z;
4197551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = o[T0 + dst.index].w;
420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						else
422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.rel.type == Shader::PARAMETER_VOID)   // Not relative
424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							{
4257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.x) pDst.x = o[dst.index].x;
4267551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.y) pDst.y = o[dst.index].y;
4277551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.z) pDst.z = o[dst.index].z;
4287551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.w) pDst.w = o[dst.index].w;
429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							}
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							else
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							{
432b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens								Int a = relativeAddress(dst);
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4347551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.x) pDst.x = o[dst.index + a].x;
4357551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.y) pDst.y = o[dst.index + a].y;
4367551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.z) pDst.z = o[dst.index + a].z;
4377551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.w) pDst.w = o[dst.index + a].w;
438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							}
439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
4417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_LABEL:                break;
4427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_PREDICATE: pDst = p0; break;
4437551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_INPUT:                break;
444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					default:
445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						ASSERT(false);
446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
448b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens					Int4 enable = enableMask(instruction);
449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 xEnable = enable;
451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 yEnable = enable;
452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 zEnable = enable;
453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 wEnable = enable;
454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					if(predicate)
456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						unsigned char pSwizzle = instruction->predicateSwizzle;
458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
4597551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 xPredicate = p0[(pSwizzle >> 0) & 0x03];
4607551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 yPredicate = p0[(pSwizzle >> 2) & 0x03];
4617551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 zPredicate = p0[(pSwizzle >> 4) & 0x03];
4627551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 wPredicate = p0[(pSwizzle >> 6) & 0x03];
463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(!instruction->predicateNot)
465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.x) xEnable = xEnable & As<Int4>(xPredicate);
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.y) yEnable = yEnable & As<Int4>(yPredicate);
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.z) zEnable = zEnable & As<Int4>(zPredicate);
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.w) wEnable = wEnable & As<Int4>(wPredicate);
470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						else
472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.x) xEnable = xEnable & ~As<Int4>(xPredicate);
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.y) yEnable = yEnable & ~As<Int4>(yPredicate);
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.z) zEnable = zEnable & ~As<Int4>(zPredicate);
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.w) wEnable = wEnable & ~As<Int4>(wPredicate);
477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = As<Float4>(As<Int4>(d.x) & xEnable);
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = As<Float4>(As<Int4>(d.y) & yEnable);
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = As<Float4>(As<Int4>(d.z) & zEnable);
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = As<Float4>(As<Int4>(d.w) & wEnable);
484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = As<Float4>(As<Int4>(d.x) | (As<Int4>(pDst.x) & ~xEnable));
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = As<Float4>(As<Int4>(d.y) | (As<Int4>(pDst.y) & ~yEnable));
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = As<Float4>(As<Int4>(d.z) | (As<Int4>(pDst.z) & ~zEnable));
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = As<Float4>(As<Int4>(d.w) | (As<Int4>(pDst.w) & ~wEnable));
489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				switch(dst.type)
492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_VOID:
494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_TEMP:
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.rel.type == Shader::PARAMETER_VOID)
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
4987551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) r[dst.index].x = d.x;
4997551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) r[dst.index].y = d.y;
5007551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) r[dst.index].z = d.z;
5017551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) r[dst.index].w = d.w;
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					else
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
505b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens						Int a = relativeAddress(dst);
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5077551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) r[dst.index + a].x = d.x;
5087551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) r[dst.index + a].y = d.y;
5097551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) r[dst.index + a].z = d.z;
5107551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) r[dst.index + a].w = d.w;
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_ADDR:
5147551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.x) a0.x = d.x;
5157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.y) a0.y = d.y;
5167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.z) a0.z = d.z;
5177551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.w) a0.w = d.w;
518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_RASTOUT:
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					switch(dst.index)
521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					case 0:
5237551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) o[Pos].x = d.x;
5247551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) o[Pos].y = d.y;
5257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) o[Pos].z = d.z;
5267551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) o[Pos].w = d.w;
527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					case 1:
5297551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						o[Fog].x = d.x;
530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
531b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens					case 2:
5327551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						o[Pts].y = d.x;
533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					default:	ASSERT(false);
535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
537b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens				case Shader::PARAMETER_ATTROUT:
538995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.x) o[C0 + dst.index].x = d.x;
539995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.y) o[C0 + dst.index].y = d.y;
540995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.z) o[C0 + dst.index].z = d.z;
541995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.w) o[C0 + dst.index].w = d.w;
542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_TEXCRDOUT:
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			//	case Shader::PARAMETER_OUTPUT:
54553ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu					if(shaderModel < 0x0300)
546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
5477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) o[T0 + dst.index].x = d.x;
5487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) o[T0 + dst.index].y = d.y;
5497551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) o[T0 + dst.index].z = d.z;
5507551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) o[T0 + dst.index].w = d.w;
551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					else
553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(dst.rel.type == Shader::PARAMETER_VOID)   // Not relative
555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
5567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) o[dst.index].x = d.x;
5577551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) o[dst.index].y = d.y;
5587551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) o[dst.index].z = d.z;
5597551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) o[dst.index].w = d.w;
560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						else
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
563b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens							Int a = relativeAddress(dst);
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5657551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) o[dst.index + a].x = d.x;
5667551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) o[dst.index + a].y = d.y;
5677551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) o[dst.index + a].z = d.z;
5687551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) o[dst.index + a].w = d.w;
569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
5727551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				case Shader::PARAMETER_LABEL:             break;
5737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				case Shader::PARAMETER_PREDICATE: p0 = d; break;
5747551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				case Shader::PARAMETER_INPUT:             break;
575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				default:
576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					ASSERT(false);
577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(currentLabel != -1)
582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::setInsertBlock(returnBlock);
584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
587b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::passThrough()
588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(shader)
590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
591ec0936c46c22cfaa1d496749dfcd7c235dca825cNicolas Capens			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
59302ad0aa756ab6cbfb6ca00b98ac6793536ff9820Alexis Hetu				unsigned char usage = shader->getOutput(i, 0).usage;
594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				switch(usage)
596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				case 0xFF:
598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					continue;
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_PSIZE:
6007551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].x;
601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_TEXCOORD:
6037551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
6047551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].y;
6057551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].z = v[i].z;
6067551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].w = v[i].w;
607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_POSITION:
6097551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
6107551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].y;
6117551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].z = v[i].z;
6127551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].w = v[i].w;
613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_COLOR:
6157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
6167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].y;
6177551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].z = v[i].z;
6187551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].w = v[i].w;
619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_FOG:
6217551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				default:
624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					ASSERT(false);
625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
6307551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].x = v[PositionT].x;
6317551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].y = v[PositionT].y;
6327551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].z = v[PositionT].z;
6337551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].w = v[PositionT].w;
634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			for(int i = 0; i < 2; i++)
636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
637995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].x = v[Color0 + i].x;
638995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].y = v[Color0 + i].y;
639995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].z = v[Color0 + i].z;
640995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].w = v[Color0 + i].w;
641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			for(int i = 0; i < 8; i++)
644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
6457551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].x = v[TexCoord0 + i].x;
6467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].y = v[TexCoord0 + i].y;
6477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].z = v[TexCoord0 + i].z;
6487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].w = v[TexCoord0 + i].w;
649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
6517551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pts].y = v[PointSize].x;
652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
655c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens	Vector4f VertexProgram::fetchRegister(const Src &src, unsigned int offset)
656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Vector4f reg;
6585d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		unsigned int i = src.index + offset;
659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(src.type)
661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_TEMP:
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(src.rel.type == Shader::PARAMETER_VOID)
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6657551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg = r[i];
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6692c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				reg = r[i + relativeAddress(src, src.bufferIndex)];
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_CONST:
673b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			reg = readConstant(src, offset);
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_INPUT:
6760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			if(src.rel.type == Shader::PARAMETER_VOID)
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6787551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg = v[i];
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6822c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				reg = v[i + relativeAddress(src, src.bufferIndex)];
68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
6840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
6857551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_VOID: return r[0];   // Dummy
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_FLOAT4LITERAL:
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.x = Float4(src.value[0]);
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.y = Float4(src.value[1]);
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.z = Float4(src.value[2]);
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.w = Float4(src.value[3]);
69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
6927551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_ADDR:      reg = a0; break;
6937551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_CONSTBOOL: return r[0];   // Dummy
6947551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_CONSTINT:  return r[0];   // Dummy
6957551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_LOOP:      return r[0];   // Dummy
6967551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_PREDICATE: return r[0];   // Dummy
69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_SAMPLER:
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(src.rel.type == Shader::PARAMETER_VOID)
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				reg.x = As<Float4>(Int4(i));
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else if(src.rel.type == Shader::PARAMETER_TEMP)
70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
7047551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg.x = As<Float4>(Int4(i) + As<Int4>(r[src.rel.index].x));
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			return reg;
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_OUTPUT:
7080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			if(src.rel.type == Shader::PARAMETER_VOID)
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
7107551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg = o[i];
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
7142c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				reg = o[i + relativeAddress(src, src.bufferIndex)];
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
717dd8df68e64365aafe91893b11bf7cc4b67599ed4Alexis Hetu		case Shader::PARAMETER_MISCTYPE:
718877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			if(src.index == Shader::InstanceIDIndex)
719877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
720877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				reg.x = As<Float>(instanceID);
721877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
722877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			else if(src.index == Shader::VertexIDIndex)
723877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
724877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				reg.x = As<Float4>(vertexID);
725877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
726877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			else ASSERT(false);
727dd8df68e64365aafe91893b11bf7cc4b67599ed4Alexis Hetu			return reg;
728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &x = reg[(src.swizzle >> 0) & 0x3];
73366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &y = reg[(src.swizzle >> 2) & 0x3];
73466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &z = reg[(src.swizzle >> 4) & 0x3];
73566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &w = reg[(src.swizzle >> 6) & 0x3];
736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		Vector4f mod;
738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(src.modifier)
740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_NONE:
74266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = x;
74366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = y;
74466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = z;
74566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = w;
746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_NEGATE:
74866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = -x;
74966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = -y;
75066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = -z;
75166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = -w;
752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_ABS:
75466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = Abs(x);
75566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = Abs(y);
75666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = Abs(z);
75766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = Abs(w);
758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_ABS_NEGATE:
76066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = -Abs(x);
76166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = -Abs(y);
76266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = -Abs(z);
76366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = -Abs(w);
764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_NOT:
76666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = As<Float4>(As<Int4>(x) ^ Int4(0xFFFFFFFF));
76766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = As<Float4>(As<Int4>(y) ^ Int4(0xFFFFFFFF));
76866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = As<Float4>(As<Int4>(z) ^ Int4(0xFFFFFFFF));
76966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = As<Float4>(As<Int4>(w) ^ Int4(0xFFFFFFFF));
770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		return mod;
776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
7782c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	RValue<Pointer<Byte>> VertexProgram::uniformAddress(int bufferIndex, unsigned int index)
7792c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	{
7802c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		if(bufferIndex == -1)
7812c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		{
7822c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			return data + OFFSET(DrawData, vs.c[index]);
7832c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		}
7842c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		else
7852c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		{
7862c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			return *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, vs.u[bufferIndex])) + index;
7872c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		}
7882c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	}
7892c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
7902c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	RValue<Pointer<Byte>> VertexProgram::uniformAddress(int bufferIndex, unsigned int index, Int& offset)
7912c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	{
7922c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		return uniformAddress(bufferIndex, index) + offset * sizeof(float4);
7932c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	}
7942c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
795b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	Vector4f VertexProgram::readConstant(const Src &src, unsigned int offset)
796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Vector4f c;
7985d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		unsigned int i = src.index + offset;
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(src.rel.type == Shader::PARAMETER_VOID)   // Not relative
80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
8022c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i));
80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.x = c.x.xxxx;
80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.y = c.y.yyyy;
80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.z = c.z.zzzz;
80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.w = c.w.wwww;
80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
809eafdb22c36f2077815eadf2a1db0fb6547bf0241Nicolas Capens			if(shader->containsDefineInstruction())   // Constant may be known at compile time
81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
811903e025f6cd8d978f013c741431b87b04ae01fd1Alexis Hetu				for(size_t j = 0; j < shader->getLength(); j++)
81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					const Shader::Instruction &instruction = *shader->getInstruction(j);
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(instruction.opcode == Shader::OPCODE_DEF)
81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(instruction.dst.index == i)
81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.x = Float4(instruction.src[0].value[0]);
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.y = Float4(instruction.src[0].value[1]);
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.z = Float4(instruction.src[0].value[2]);
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.w = Float4(instruction.src[0].value[3]);
82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							break;
82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						}
82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(src.rel.type == Shader::PARAMETER_LOOP)
83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
8327551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			Int loopCounter = aL[loopDepth];
83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8342c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, loopCounter));
83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.x = c.x.xxxx;
83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.y = c.y.yyyy;
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.z = c.z.zzzz;
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.w = c.w.wwww;
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(src.rel.deterministic)
84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
8452c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				Int a = relativeAddress(src, src.bufferIndex);
846c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
8472c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, a));
848b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.x = c.x.xxxx;
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.y = c.y.yyyy;
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.z = c.z.zzzz;
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.w = c.w.wwww;
85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				int component = src.rel.swizzle & 0x03;
85719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Float4 a;
85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				switch(src.rel.type)
86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
86132980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_ADDR:     a = a0[component]; break;
86232980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_TEMP:     a = r[src.rel.index][component]; break;
86332980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_INPUT:    a = v[src.rel.index][component]; break;
86432980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_OUTPUT:   a = o[src.rel.index][component]; break;
86532980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_CONST:    a = *Pointer<Float>(uniformAddress(src.bufferIndex, src.rel.index) + component * sizeof(float)); break;
866877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				case Shader::PARAMETER_MISCTYPE:
867877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					if(src.rel.index == Shader::InstanceIDIndex)
868877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					{
869877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu						a = As<Float4>(Int4(instanceID)); break;
870877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					}
871877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					else if(src.rel.index == Shader::VertexIDIndex)
872877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					{
873877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu						a = As<Float4>(vertexID); break;
874877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					}
875877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					else ASSERT(false);
876877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					break;
87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				default: ASSERT(false);
87819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
87919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88002a2bb807c1e947bc99d68ba7dd4984289278be0Alexis Hetu				Int4 index = Int4(i) + As<Int4>(a) * Int4(src.rel.scale);
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
882028f41ba4d7b96e4281d69183ded014b69ab7c2cAlexis Hetu				index = Min(As<UInt4>(index), UInt4(VERTEX_UNIFORM_VECTORS));   // Clamp to constant register range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
883b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index0 = Extract(index, 0);
88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index1 = Extract(index, 1);
88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index2 = Extract(index, 2);
88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index3 = Extract(index, 3);
88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8892c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.x = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index0), 16);
8902c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.y = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index1), 16);
8912c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.z = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index2), 16);
8922c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index3), 16);
89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				transpose4x4(c.x, c.y, c.z, c.w);
89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return c;
89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9012c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	Int VertexProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		ASSERT(var.rel.deterministic);
90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(var.rel.type == Shader::PARAMETER_TEMP)
90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
9077551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return As<Int>(Extract(r[var.rel.index].x, 0)) * var.rel.scale;
90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(var.rel.type == Shader::PARAMETER_INPUT)
91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
9117551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return As<Int>(Extract(v[var.rel.index].x, 0)) * var.rel.scale;
91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(var.rel.type == Shader::PARAMETER_OUTPUT)
91419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
9157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return As<Int>(Extract(o[var.rel.index].x, 0)) * var.rel.scale;
91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(var.rel.type == Shader::PARAMETER_CONST)
91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
91948be735fa7eb1e2684a631cc4270a4503c7d235aAlexis Hetu			return *Pointer<Int>(uniformAddress(bufferIndex, var.rel.index)) * var.rel.scale;
92019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
921907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		else if(var.rel.type == Shader::PARAMETER_LOOP)
922907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		{
9237551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return aL[loopDepth];
924907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		}
92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else ASSERT(false);
92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return 0;
92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
930b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	Int4 VertexProgram::enableMask(const Shader::Instruction *instruction)
93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
9327551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
933b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
934d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman		if(!whileTest)
93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
936d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			if(shader->containsBreakInstruction() && instruction->analysisBreak)
937d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			{
9387551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				enable &= enableBreak;
939d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			}
94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
941d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			if(shader->containsContinueInstruction() && instruction->analysisContinue)
942d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			{
9437551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				enable &= enableContinue;
944d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			}
94519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
946d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			if(shader->containsLeaveInstruction() && instruction->analysisLeave)
947d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			{
9487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				enable &= enableLeave;
949d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			}
95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return enable;
95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
955b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M3X2(Vector4f &dst, Vector4f &src0, Src &src1)
95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
957c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
958c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot3(src0, row0);
961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot3(src0, row1);
962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
964b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M3X3(Vector4f &dst, Vector4f &src0, Src &src1)
965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
966c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
967c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
968c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot3(src0, row0);
971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot3(src0, row1);
972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot3(src0, row2);
973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
975b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M3X4(Vector4f &dst, Vector4f &src0, Src &src1)
976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
977c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
978c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
979c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
980c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row3 = fetchRegister(src1, 3);
981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot3(src0, row0);
983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot3(src0, row1);
984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot3(src0, row2);
985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.w = dot3(src0, row3);
986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
988b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M4X3(Vector4f &dst, Vector4f &src0, Src &src1)
989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
990c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
991c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
992c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot4(src0, row0);
995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot4(src0, row1);
996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot4(src0, row2);
997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
999b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M4X4(Vector4f &dst, Vector4f &src0, Src &src1)
1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1001c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1002c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1003c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
1004c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row3 = fetchRegister(src1, 3);
1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot4(src0, row0);
1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot4(src0, row1);
1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot4(src0, row2);
1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.w = dot4(src0, row3);
1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1012b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAK()
1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1014c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *deadBlock = Nucleus::createBasicBlock();
1015c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1];
1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(breakDepth == 0)
1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
10197551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableIndex = enableIndex - breakDepth;
1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createBr(endBlock);
1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
10247551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableBreak = enableBreak & ~enableStack[enableIndex];
10257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			Bool allBreak = SignMask(enableBreak) == 0x0;
1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10277551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableIndex = enableIndex - breakDepth;
1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			branch(allBreak, endBlock, deadBlock);
1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(deadBlock);
10327551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex = enableIndex + breakDepth;
1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1035b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control)
1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Int4 condition;
1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(control)
1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
104119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_GT: condition = CmpNLE(src0.x,  src1.x);	break;
104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x);		break;
104319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x);	break;
104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_LT: condition = CmpLT(src0.x,  src1.x);	break;
104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x);	break;
104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x);		break;
1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1051b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		BREAK(condition);
1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1054b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAKP(const Src &predicateRegister)   // FIXME: Factor out parts common with BREAKC
1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
10567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
105819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			condition = ~condition;
1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1063b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		BREAK(condition);
106419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
106519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1066b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAK(Int4 &condition)
106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
10687551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex];
1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1070c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *continueBlock = Nucleus::createBasicBlock();
1071c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1];
1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = enableBreak & ~condition;
10747551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Bool allBreak = SignMask(enableBreak) == 0x0;
1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10767551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex = enableIndex - breakDepth;
1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		branch(allBreak, endBlock, continueBlock);
107819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(continueBlock);
10807551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex = enableIndex + breakDepth;
1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1083b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CONTINUE()
108419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
10857551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableContinue = enableContinue & ~enableStack[enableIndex];
108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
108719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
108819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	void VertexProgram::TEST()
108919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		whileTest = true;
109119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
109219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1093b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALL(int labelIndex, int callSiteIndex)
1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!labelBlock[labelIndex])
1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
110019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(callRetBlock[labelIndex].size() > 1)
110119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
11027551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
110319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11057551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreLeave = enableLeave;
1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(labelBlock[labelIndex]);
110819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
110919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11107551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = restoreLeave;
1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1113b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALLNZ(int labelIndex, int callSiteIndex, const Src &src)
1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
111519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(src.type == Shader::PARAMETER_CONSTBOOL)
1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1117b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			CALLNZb(labelIndex, callSiteIndex, src);
1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
111919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(src.type == Shader::PARAMETER_PREDICATE)
1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1121b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			CALLNZp(labelIndex, callSiteIndex, src);
1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else ASSERT(false);
1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1126b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister)
1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
11287551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Bool condition = (*Pointer<Byte>(data + OFFSET(DrawData,vs.b[boolRegister.index])) != Byte(0));   // FIXME
1129b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
113019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(boolRegister.modifier == Shader::MODIFIER_NOT)
1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1132b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			condition = !condition;
1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!labelBlock[labelIndex])
1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
114019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(callRetBlock[labelIndex].size() > 1)
114119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
11427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
114319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11457551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreLeave = enableLeave;
1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
114719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		branch(condition, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]);
114819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
114919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11507551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = restoreLeave;
1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1153b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister)
1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
11557551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			condition = ~condition;
1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11627551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex];
1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!labelBlock[labelIndex])
1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(callRetBlock[labelIndex].size() > 1)
117019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
11717551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
117219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11747551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex++;
11757551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[enableIndex] = condition;
11767551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreLeave = enableLeave;
1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
117819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Bool notAllFalse = SignMask(condition) != 0;
117919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		branch(notAllFalse, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]);
118019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11827551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex--;
11837551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = restoreLeave;
1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1186b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ELSE()
1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth--;
1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1190c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = ifFalseBlock[ifDepth];
1191c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(isConditionalIf[ifDepth])
1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
11957551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			Int4 condition = ~enableStack[enableIndex] & enableStack[enableIndex - 1];
119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Bool notAllFalse = SignMask(condition) != 0;
1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			branch(notAllFalse, falseBlock, endBlock);
1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12007551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableStack[enableIndex] = ~enableStack[enableIndex] & enableStack[enableIndex - 1];
1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createBr(endBlock);
1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::setInsertBlock(falseBlock);
1206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifFalseBlock[ifDepth] = endBlock;
1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth++;
1211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1213b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDIF()
1214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth--;
1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1217c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = ifFalseBlock[ifDepth];
1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(endBlock);
1220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(endBlock);
1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(isConditionalIf[ifDepth])
1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			breakDepth--;
12257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableIndex--;
1226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1229b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDLOOP()
1230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth--;
1232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12337551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		aL[loopDepth] = aL[loopDepth] + increment[loopDepth];   // FIXME: +=
123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1235c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1236c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(endBlock);
1240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth--;
12427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1245b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDREP()
1246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth--;
1248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1249c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1250c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(endBlock);
1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12557551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth--;
12567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1259b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDWHILE()
126019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
126119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepDepth--;
126219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1263c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1264c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::createBr(testBlock);
126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(endBlock);
126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12697551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex--;
12707551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		whileTest = false;
127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
127319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12749aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	void VertexProgram::ENDSWITCH()
12759aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	{
12769aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepDepth--;
12779aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1278c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1279ec0936c46c22cfaa1d496749dfcd7c235dca825cNicolas Capens
12809aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		Nucleus::createBr(loopRepEndBlock[loopRepDepth]);
12819aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		Nucleus::setInsertBlock(endBlock);
12829aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
12839aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		enableIndex--;
12849aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
12859aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	}
12869aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1287b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IF(const Src &src)
1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
128919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(src.type == Shader::PARAMETER_CONSTBOOL)
1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1291b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			IFb(src);
1292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
129319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(src.type == Shader::PARAMETER_PREDICATE)
1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1295b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			IFp(src);
1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
129719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else
129819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
1299c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Int4 condition = As<Int4>(fetchRegister(src).x);
1300b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			IF(condition);
130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1304b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IFb(const Src &boolRegister)
1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ASSERT(ifDepth < 24 + 4);
1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13087551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Bool condition = (*Pointer<Byte>(data + OFFSET(DrawData,vs.b[boolRegister.index])) != Byte(0));   // FIXME
1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
131019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(boolRegister.modifier == Shader::MODIFIER_NOT)
1311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
131219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			condition = !condition;
1313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1315c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *trueBlock = Nucleus::createBasicBlock();
1316c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = Nucleus::createBasicBlock();
1317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		branch(condition, trueBlock, falseBlock);
1319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		isConditionalIf[ifDepth] = false;
1321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifFalseBlock[ifDepth] = falseBlock;
1322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth++;
1324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1326b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IFp(const Src &predicateRegister)
1327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
13287551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
133019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			condition = ~condition;
1333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1335b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		IF(condition);
1336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1338b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IFC(Vector4f &src0, Vector4f &src1, Control control)
1339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Int4 condition;
1341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(control)
1343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_GT: condition = CmpNLE(src0.x,  src1.x);	break;
134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x);		break;
134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x);	break;
134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_LT: condition = CmpLT(src0.x,  src1.x);	break;
134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x);	break;
134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x);		break;
1350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
1351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
1352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1354b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		IF(condition);
135519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
135619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1357b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IF(Int4 &condition)
135819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
13597551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex];
1360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13617551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex++;
13627551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[enableIndex] = condition;
1363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1364c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *trueBlock = Nucleus::createBasicBlock();
1365c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = Nucleus::createBasicBlock();
1366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Bool notAllFalse = SignMask(condition) != 0;
1368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		branch(notAllFalse, trueBlock, falseBlock);
1370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		isConditionalIf[ifDepth] = true;
1372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifFalseBlock[ifDepth] = falseBlock;
1373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth++;
1375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		breakDepth++;
1376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	void VertexProgram::LABEL(int labelIndex)
1379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
138019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(!labelBlock[labelIndex])
138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
138219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(labelBlock[labelIndex]);
138619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		currentLabel = labelIndex;
1387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1389b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::LOOP(const Src &integerRegister)
1390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
13917551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth++;
1392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13937551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][0]));
13947551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		aL[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][1]));
13957551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		increment[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][2]));
1396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		// FIXME: Compiles to two instructions?
13987551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		If(increment[loopDepth] == 0)
1399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
14007551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			increment[loopDepth] = 1;
1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1403c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1404c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1405c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepTestBlock[loopRepDepth] = testBlock;
1408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepEndBlock[loopRepDepth] = endBlock;
1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		// FIXME: jump(testBlock)
1411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(testBlock);
1413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14147551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		branch(iteration[loopDepth] > 0, loopBlock, endBlock);
1415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(loopBlock);
1416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14177551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = iteration[loopDepth] - 1;   // FIXME: --
1418b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
1419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth++;
1420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		breakDepth = 0;
1421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1423b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::REP(const Src &integerRegister)
1424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
14257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth++;
1426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14277551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][0]));
14287551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		aL[loopDepth] = aL[loopDepth - 1];
1429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1430c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1431c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1432c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepTestBlock[loopRepDepth] = testBlock;
1435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepEndBlock[loopRepDepth] = endBlock;
1436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		// FIXME: jump(testBlock)
1438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(testBlock);
1440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		branch(iteration[loopDepth] > 0, loopBlock, endBlock);
1442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(loopBlock);
1443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14447551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = iteration[loopDepth] - 1;   // FIXME: --
1445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth++;
1447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		breakDepth = 0;
1448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1450b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::WHILE(const Src &temporaryRegister)
145119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
14527551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex++;
145319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1454c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1455c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1456c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1457b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
145819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepTestBlock[loopRepDepth] = testBlock;
145919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepEndBlock[loopRepDepth] = endBlock;
146019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14617551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreBreak = enableBreak;
14627551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreContinue = enableContinue;
146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
146419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// FIXME: jump(testBlock)
146519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::createBr(testBlock);
146619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(testBlock);
14677551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableContinue = restoreContinue;
146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1469c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		const Vector4f &src = fetchRegister(temporaryRegister);
147019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Int4 condition = As<Int4>(src.x);
14717551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex - 1];
14722ff2948b730812543a6d0702377084c472e3404dNicolas Capens		if(shader->containsLeaveInstruction()) condition &= enableLeave;
14737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[enableIndex] = condition;
147419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
147519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Bool notAllFalse = SignMask(condition) != 0;
147619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		branch(notAllFalse, loopBlock, endBlock);
1477b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
147819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(endBlock);
14797551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = restoreBreak;
1480b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
148119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(loopBlock);
148219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
148319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepDepth++;
148419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		breakDepth = 0;
148519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
14869aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
14879aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	void VertexProgram::SWITCH()
14889aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	{
14899aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		enableIndex++;
14909aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		enableStack[enableIndex] = Int4(0xFFFFFFFF);
14919aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1492c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
14939aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
14949aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepTestBlock[loopRepDepth] = nullptr;
14959aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepEndBlock[loopRepDepth] = endBlock;
14969aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
14979aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepDepth++;
14989aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		breakDepth = 0;
14999aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	}
150019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1501b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::RET()
1502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
150319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(currentLabel == -1)
1504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			returnBlock = Nucleus::createBasicBlock();
1506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createBr(returnBlock);
1507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
1509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1510c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens			BasicBlock *unreachableBlock = Nucleus::createBasicBlock();
1511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
151219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(callRetBlock[currentLabel].size() > 1)   // Pop the return destination from the call stack
1513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
151419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				// FIXME: Encapsulate
15157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				UInt index = callStack[--stackIndex];
1516b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
15171933654b62251805d4575b05b6829275b0fe6142Nicolas Capens				Value *value = index.loadValue();
1518b98fe5cd1eaa821083d816cf86a20eefe22f57c7Nicolas Capens				SwitchCases *switchCases = Nucleus::createSwitch(value, unreachableBlock, (int)callRetBlock[currentLabel].size());
151919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
152019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				for(unsigned int i = 0; i < callRetBlock[currentLabel].size(); i++)
152119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
1522b98fe5cd1eaa821083d816cf86a20eefe22f57c7Nicolas Capens					Nucleus::addSwitchCase(switchCases, i, callRetBlock[currentLabel][i]);
152319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
152419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
152519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else if(callRetBlock[currentLabel].size() == 1)   // Jump directly to the unique return destination
152619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
152719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Nucleus::createBr(callRetBlock[currentLabel][0]);
152819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
152919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else   // Function isn't called
153019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
153119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Nucleus::createBr(unreachableBlock);
1532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
1533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::setInsertBlock(unreachableBlock);
1535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createUnreachable();
1536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1539b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::LEAVE()
1540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
15417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = enableLeave & ~enableStack[enableIndex];
154219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
154319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// FIXME: Return from function if all instances left
154419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// FIXME: Use enableLeave in other control-flow constructs
154519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
1546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1547a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1)
154819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
1549a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), (src0), Base);
155019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
1551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1552a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
155319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
1554a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Base, Offset});
1555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
155619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1557a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
155825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1559a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
156025d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
156125d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1562a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
156325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1564a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
156525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
156625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1567a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
156825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1569a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
157025d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
157125d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1572a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
157325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1574a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
157525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
157625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1577a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
157825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1579a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, src0, Grad);
158025d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
158125d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1582a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
158325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1584a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
158525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
158625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1587b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
15889bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu	{
158995ac1874dbdc4db63ff18279a1f8590d4b10b647Alexis Hetu		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[16]) + src1.index * sizeof(Texture);
159089a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		dst = SamplerCore::textureSize(texture, lod);
15919bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu	}
15929bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu
1593a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	Vector4f VertexProgram::sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
159419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
1595c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f tmp;
1596c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
159719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID)
159819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
1599a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			tmp = sampleTexture(s.index, uvwq, lod, dsx, dsy, offset, function);
160019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
160119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else
160219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
1603c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Int index = As<Int>(Float(fetchRegister(s).x.x));
160419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1605c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
160619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
160719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				if(shader->usesSampler(i))
160819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
160919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					If(index == i)
161019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
1611a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens						tmp = sampleTexture(i, uvwq, lod, dsx, dsy, offset, function);
161219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
161319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
161419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
161519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
161619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1617c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
161889a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		Vector4f c;
1619c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.x = tmp[(s.swizzle >> 0) & 0x3];
1620c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.y = tmp[(s.swizzle >> 2) & 0x3];
1621c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.z = tmp[(s.swizzle >> 4) & 0x3];
1622c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.w = tmp[(s.swizzle >> 6) & 0x3];
162389a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens
162489a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		return c;
162589a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens	}
162689a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens
1627a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	Vector4f VertexProgram::sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
162889a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens	{
162989a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + sampler * sizeof(Texture);
1630a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		return SamplerCore(constants, state.sampler[sampler]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, lod, dsx, dsy, offset, function);
163119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
1632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1633