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;
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		currentLabel = -1;
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		whileTest = false;
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		for(int i = 0; i < 2048; i++)
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[i] = 0;
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
387551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
397551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth = -1;
407551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
42c62fad3b19a06381ee9b82d84775698832cc4ea3Nicolas Capens		if(shader->containsBreakInstruction())
437551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		{
447551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
457551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		}
467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
47c62fad3b19a06381ee9b82d84775698832cc4ea3Nicolas Capens		if(shader->containsContinueInstruction())
487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		{
497551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
507551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		}
517551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
5202ad0aa756ab6cbfb6ca00b98ac6793536ff9820Alexis Hetu		if(shader->isInstanceIdDeclared())
537551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		{
547551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			instanceID = *Pointer<Int>(data + OFFSET(DrawData,instanceID));
557551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		}
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	VertexProgram::~VertexProgram()
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
62877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu	void VertexProgram::pipeline(UInt& index)
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!state.preTransformed)
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
66877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			program(index);
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
70b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			passThrough();
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
74877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu	void VertexProgram::program(UInt& index)
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	//	shader->print("VertexShader-%0.8X.txt", state.shaderID);
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
7853ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu		unsigned short shaderModel = shader->getShaderModel();
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
807551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex = 0;
817551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		stackIndex = 0;
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
834677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens		if(shader->containsLeaveInstruction())
844677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens		{
857551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
864677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens		}
874677a5f7a837e06dac90521eee0cf063cbfb9c9bNicolas Capens
88877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu		if(shader->isVertexIdDeclared())
89877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu		{
90877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			if(state.textureSampling)
91877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
92877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Int4(index);
93877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
94877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			else
95877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
96877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index), 0);
97877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index + 1), 1);
98877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index + 2), 2);
99877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				vertexID = Insert(vertexID, As<Int>(index + 3), 3);
100877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
101877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu		}
102877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// Create all call site return blocks up front
104903e025f6cd8d978f013c741431b87b04ae01fd1Alexis Hetu		for(size_t i = 0; i < shader->getLength(); i++)
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			const Shader::Instruction *instruction = shader->getInstruction(i);
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Shader::Opcode opcode = instruction->opcode;
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(opcode == Shader::OPCODE_CALL || opcode == Shader::OPCODE_CALLNZ)
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				const Dst &dst = instruction->dst;
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				ASSERT(callRetBlock[dst.label].size() == dst.callSite);
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				callRetBlock[dst.label].push_back(Nucleus::createBasicBlock());
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
117b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
118903e025f6cd8d978f013c741431b87b04ae01fd1Alexis Hetu		for(size_t i = 0; i < shader->getLength(); i++)
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			const Shader::Instruction *instruction = shader->getInstruction(i);
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Shader::Opcode opcode = instruction->opcode;
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(opcode == Shader::OPCODE_DCL || opcode == Shader::OPCODE_DEF || opcode == Shader::OPCODE_DEFI || opcode == Shader::OPCODE_DEFB)
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				continue;
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Dst dst = instruction->dst;
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Src src0 = instruction->src[0];
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Src src1 = instruction->src[1];
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Src src2 = instruction->src[2];
132c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			Src src3 = instruction->src[3];
13325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu			Src src4 = instruction->src[4];
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			bool predicate = instruction->predicate;
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Control control = instruction->control;
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			bool integer = dst.type == Shader::PARAMETER_ADDR;
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			bool pp = dst.partialPrecision;
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f d;
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f s0;
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f s1;
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Vector4f s2;
144c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			Vector4f s3;
14525d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu			Vector4f s4;
146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
147c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0);
148c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1);
149c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2);
150c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegister(src3);
151c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegister(src4);
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			switch(opcode)
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
155b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_1_0:                                     break;
156b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_1_1:                                     break;
157b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_2_0:                                     break;
158b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_2_x:                                     break;
159b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_2_sw:                                    break;
160b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_3_0:                                     break;
161b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_VS_3_sw:                                    break;
162b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DCL:                                        break;
163b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DEF:                                        break;
164b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DEFI:                                       break;
165b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DEFB:                                       break;
166b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NOP:                                        break;
167b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ABS:        abs(d, s0);                     break;
1680f4480780a2bfad69cece5fd9cabd1bf89f7393eAlexis Hetu			case Shader::OPCODE_IABS:       iabs(d, s0);                    break;
169b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ADD:        add(d, s0, s1);                 break;
1708d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IADD:       iadd(d, s0, s1);                break;
171b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CRS:        crs(d, s0, s1);                 break;
172b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD1:   forward1(d, s0, s1, s2);        break;
173b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD2:   forward2(d, s0, s1, s2);        break;
174b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD3:   forward3(d, s0, s1, s2);        break;
175b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FORWARD4:   forward4(d, s0, s1, s2);        break;
176b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT1:   reflect1(d, s0, s1);            break;
177b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT2:   reflect2(d, s0, s1);            break;
178b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT3:   reflect3(d, s0, s1);            break;
179b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFLECT4:   reflect4(d, s0, s1);            break;
180b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT1:   refract1(d, s0, s1, s2.x);      break;
181b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT2:   refract2(d, s0, s1, s2.x);      break;
182b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT3:   refract3(d, s0, s1, s2.x);      break;
183b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REFRACT4:   refract4(d, s0, s1, s2.x);      break;
184b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP1:        dp1(d, s0, s1);                 break;
185b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP2:        dp2(d, s0, s1);                 break;
186b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP3:        dp3(d, s0, s1);                 break;
187b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DP4:        dp4(d, s0, s1);                 break;
188c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET2:       det2(d, s0, s1);                break;
189c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET3:       det3(d, s0, s1, s2);            break;
190c3d95f36258143af6cca041ede521995d8f890eaAlexis Hetu			case Shader::OPCODE_DET4:       det4(d, s0, s1, s2, s3);        break;
191b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATT:        att(d, s0, s1);                 break;
192b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXP2X:      exp2x(d, s0, pp);               break;
193b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXP2:       exp2(d, s0, pp);                break;
19453ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu			case Shader::OPCODE_EXPP:       expp(d, s0, shaderModel);       break;
195b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXP:        exp(d, s0, pp);                 break;
196b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_FRC:        frc(d, s0);                     break;
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			case Shader::OPCODE_TRUNC:      trunc(d, s0);                   break;
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			case Shader::OPCODE_FLOOR:      floor(d, s0);                   break;
199af1970ce7685ea66dd02ac462d6f2723d6f6e500Alexis Hetu			case Shader::OPCODE_ROUND:      round(d, s0);                   break;
200b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ROUNDEVEN:  roundEven(d, s0);               break;
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			case Shader::OPCODE_CEIL:       ceil(d, s0);                    break;
202b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LIT:        lit(d, s0);                     break;
203b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOG2X:      log2x(d, s0, pp);               break;
204b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOG2:       log2(d, s0, pp);                break;
20553ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu			case Shader::OPCODE_LOGP:       logp(d, s0, shaderModel);       break;
206b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOG:        log(d, s0, pp);                 break;
207b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LRP:        lrp(d, s0, s1, s2);             break;
208b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_STEP:       step(d, s0, s1);                break;
209b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SMOOTH:     smooth(d, s0, s1, s2);          break;
2108ef6d1097d9fe71a2461a5040bddb1893bdbed6cAlexis Hetu			case Shader::OPCODE_ISINF:      isinf(d, s0);                   break;
2118ef6d1097d9fe71a2461a5040bddb1893bdbed6cAlexis Hetu			case Shader::OPCODE_ISNAN:      isnan(d, s0);                   break;
2128d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_FLOATBITSTOINT:
2138d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_FLOATBITSTOUINT:
2148d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_INTBITSTOFLOAT:
2158d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UINTBITSTOFLOAT: d = s0;                    break;
2169cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_PACKSNORM2x16:   packSnorm2x16(d, s0);      break;
2179cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_PACKUNORM2x16:   packUnorm2x16(d, s0);      break;
218ffb35eb4ab1b99c9bb6583c39211386fa577ef02Alexis Hetu			case Shader::OPCODE_PACKHALF2x16:    packHalf2x16(d, s0);       break;
2199cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_UNPACKSNORM2x16: unpackSnorm2x16(d, s0);    break;
2209cde974d985eaa5c76ceb832e59fa54939050f5dAlexis Hetu			case Shader::OPCODE_UNPACKUNORM2x16: unpackUnorm2x16(d, s0);    break;
221ffb35eb4ab1b99c9bb6583c39211386fa577ef02Alexis Hetu			case Shader::OPCODE_UNPACKHALF2x16:  unpackHalf2x16(d, s0);     break;
222b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M3X2:       M3X2(d, s0, src1);              break;
223b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M3X3:       M3X3(d, s0, src1);              break;
224b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M3X4:       M3X4(d, s0, src1);              break;
225b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M4X3:       M4X3(d, s0, src1);              break;
226b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_M4X4:       M4X4(d, s0, src1);              break;
227b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MAD:        mad(d, s0, s1, s2);             break;
228b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_IMAD:       imad(d, s0, s1, s2);            break;
229b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MAX:        max(d, s0, s1);                 break;
2308d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMAX:       imax(d, s0, s1);                break;
2318d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMAX:       umax(d, s0, s1);                break;
232b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MIN:        min(d, s0, s1);                 break;
2338d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMIN:       imin(d, s0, s1);                break;
2348d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMIN:       umin(d, s0, s1);                break;
235b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MOV:        mov(d, s0, integer);            break;
23602a2bb807c1e947bc99d68ba7dd4984289278be0Alexis Hetu			case Shader::OPCODE_MOVA:       mov(d, s0, true);               break;
2378d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_NEG:        neg(d, s0);                     break;
2388d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_INEG:       ineg(d, s0);                    break;
239b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_F2B:        f2b(d, s0);                     break;
240b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_B2F:        b2f(d, s0);                     break;
2418d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_F2I:        f2i(d, s0);                     break;
2428d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_I2F:        i2f(d, s0);                     break;
2438d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_F2U:        f2u(d, s0);                     break;
2448d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_U2F:        u2f(d, s0);                     break;
2458d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_I2B:        i2b(d, s0);                     break;
2468d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_B2I:        b2i(d, s0);                     break;
247b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MUL:        mul(d, s0, s1);                 break;
2488d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMUL:       imul(d, s0, s1);                break;
249b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NRM2:       nrm2(d, s0, pp);                break;
250b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NRM3:       nrm3(d, s0, pp);                break;
251b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_NRM4:       nrm4(d, s0, pp);                break;
252b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_POWX:       powx(d, s0, s1, pp);            break;
253b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_POW:        pow(d, s0, s1, pp);             break;
254b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RCPX:       rcpx(d, s0, pp);                break;
255b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIV:        div(d, s0, s1);                 break;
2568d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IDIV:       idiv(d, s0, s1);                break;
2578d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UDIV:       udiv(d, s0, s1);                break;
258b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_MOD:        mod(d, s0, s1);                 break;
2598d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_IMOD:       imod(d, s0, s1);                break;
2608d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UMOD:       umod(d, s0, s1);                break;
2618d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_SHL:        shl(d, s0, s1);                 break;
262b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ISHR:       ishr(d, s0, s1);                break;
263b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_USHR:       ushr(d, s0, s1);                break;
264b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RSQX:       rsqx(d, s0, pp);                break;
265b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SQRT:       sqrt(d, s0, pp);                break;
266b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RSQ:        rsq(d, s0, pp);                 break;
267b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEN2:       len2(d.x, s0, pp);              break;
268b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEN3:       len3(d.x, s0, pp);              break;
269b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEN4:       len4(d.x, s0, pp);              break;
270b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST1:      dist1(d.x, s0, s1, pp);         break;
271b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST2:      dist2(d.x, s0, s1, pp);         break;
272b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST3:      dist3(d.x, s0, s1, pp);         break;
273b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_DIST4:      dist4(d.x, s0, s1, pp);         break;
274b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SGE:        step(d, s1, s0);                break;
275b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SGN:        sgn(d, s0);                     break;
2760f4480780a2bfad69cece5fd9cabd1bf89f7393eAlexis Hetu			case Shader::OPCODE_ISGN:       isgn(d, s0);                    break;
277b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SINCOS:     sincos(d, s0, pp);              break;
278b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_COS:        cos(d, s0, pp);                 break;
279b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SIN:        sin(d, s0, pp);                 break;
280b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TAN:        tan(d, s0);                     break;
281b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ACOS:       acos(d, s0);                    break;
282b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ASIN:       asin(d, s0);                    break;
283b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATAN:       atan(d, s0);                    break;
284b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATAN2:      atan2(d, s0, s1);               break;
285b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_COSH:       cosh(d, s0, pp);                break;
286b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SINH:       sinh(d, s0, pp);                break;
287b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TANH:       tanh(d, s0, pp);                break;
288b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ACOSH:      acosh(d, s0, pp);               break;
289b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ASINH:      asinh(d, s0, pp);               break;
290b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ATANH:      atanh(d, s0, pp);               break;
291b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SLT:        slt(d, s0, s1);                 break;
292b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SUB:        sub(d, s0, s1);                 break;
2938d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_ISUB:       isub(d, s0, s1);                break;
294b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_BREAK:      BREAK();                        break;
295b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_BREAKC:     BREAKC(s0, s1, control);        break;
296b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_BREAKP:     BREAKP(src0);                   break;
297b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CONTINUE:   CONTINUE();                     break;
298b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEST:       TEST();                         break;
299b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CALL:       CALL(dst.label, dst.callSite);  break;
300b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CALLNZ:     CALLNZ(dst.label, dst.callSite, src0); break;
301b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ELSE:       ELSE();                         break;
302b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDIF:      ENDIF();                        break;
303b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDLOOP:    ENDLOOP();                      break;
304b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDREP:     ENDREP();                       break;
305b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ENDWHILE:   ENDWHILE();                     break;
3069aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu			case Shader::OPCODE_ENDSWITCH:  ENDSWITCH();                    break;
307b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_IF:         IF(src0);                       break;
308b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_IFC:        IFC(s0, s1, control);           break;
309b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LABEL:      LABEL(dst.index);               break;
310b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LOOP:       LOOP(src1);                     break;
311b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_REP:        REP(src0);                      break;
312b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_WHILE:      WHILE(src0);                    break;
3139aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu			case Shader::OPCODE_SWITCH:     SWITCH();                       break;
314b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_RET:        RET();                          break;
315b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_LEAVE:      LEAVE();                        break;
316b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_CMP:        cmp(d, s0, s1, control);        break;
317b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ICMP:       icmp(d, s0, s1, control);       break;
3188d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_UCMP:       ucmp(d, s0, s1, control);       break;
319b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_SELECT:     select(d, s0, s1, s2);          break;
320b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_EXTRACT:    extract(d.x, s0, s1.x);         break;
321b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_INSERT:     insert(d, s0, s1.x, s2.x);      break;
322b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ALL:        all(d.x, s0);                   break;
323b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_ANY:        any(d.x, s0);                   break;
32424f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_NOT:        bitwise_not(d, s0);             break;
32524f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_OR:         bitwise_or(d, s0, s1);          break;
32624f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_XOR:        bitwise_xor(d, s0, s1);         break;
32724f454e25c47452bbeaeab4175865b706e9ab03aAlexis Hetu			case Shader::OPCODE_AND:        bitwise_and(d, s0, s1);         break;
3288d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_EQ:         equal(d, s0, s1);               break;
3298d78cf77ce7c6bc4ba320fefb2cd2b74cc408b1aAlexis Hetu			case Shader::OPCODE_NE:         notEqual(d, s0, s1);            break;
330a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLDL:     TEXLOD(d, s0, src1, s0.w);      break;
331a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLOD:     TEXLOD(d, s0, src1, s2.x);      break;
332b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEX:        TEX(d, s0, src1);               break;
3332337a192aa163b1076ba768e414c5fe27f1a9143Meng-Lin Wu			case Shader::OPCODE_TEXOFFSET:  TEXOFFSET(d, s0, src1, s2);     break;
334a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x); break;
335a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x);  break;
336a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
337b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEXGRAD:    TEXGRAD(d, s0, src1, s2, s3);   break;
338a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
339b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_TEXSIZE:    TEXSIZE(d, s0.x, src1);         break;
340b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			case Shader::OPCODE_END:                                        break;
341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			default:
342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				ASSERT(false);
343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(dst.type != Shader::PARAMETER_VOID && dst.type != Shader::PARAMETER_LABEL && opcode != Shader::OPCODE_NOP)
346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				if(dst.saturate)
348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = Max(d.x, Float4(0.0f));
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = Max(d.y, Float4(0.0f));
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = Max(d.z, Float4(0.0f));
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = Max(d.w, Float4(0.0f));
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = Min(d.x, Float4(1.0f));
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = Min(d.y, Float4(1.0f));
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = Min(d.z, Float4(1.0f));
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = Min(d.w, Float4(1.0f));
358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
360c6e8ab13ecf20217229de8f4f19a14bbc18778f9Nicolas Capens				if(instruction->isPredicated())
361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					Vector4f pDst;   // FIXME: Rename
363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					switch(dst.type)
365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
366b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens					case Shader::PARAMETER_VOID: break;
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_TEMP:
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(dst.rel.type == Shader::PARAMETER_VOID)
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
3707551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = r[dst.index].x;
3717551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = r[dst.index].y;
3727551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = r[dst.index].z;
3737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = r[dst.index].w;
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						}
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						else
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
377b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens							Int a = relativeAddress(dst);
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3797551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = r[dst.index + a].x;
3807551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = r[dst.index + a].y;
3817551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = r[dst.index + a].z;
3827551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = r[dst.index + a].w;
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						}
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						break;
3857551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_ADDR: pDst = a0; break;
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_RASTOUT:
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						switch(dst.index)
388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						case 0:
3907551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = o[Pos].x;
3917551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = o[Pos].y;
3927551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = o[Pos].z;
3937551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = o[Pos].w;
394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							break;
395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						case 1:
3967551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							pDst.x = o[Fog].x;
397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							break;
398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						case 2:
3997551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							pDst.x = o[Pts].y;
400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							break;
401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						default:
402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							ASSERT(false);
403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_ATTROUT:
406995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.x) pDst.x = o[C0 + dst.index].x;
407995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.y) pDst.y = o[C0 + dst.index].y;
408995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.z) pDst.z = o[C0 + dst.index].z;
409995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens						if(dst.w) pDst.w = o[C0 + dst.index].w;
410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					case Shader::PARAMETER_TEXCRDOUT:
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				//	case Shader::PARAMETER_OUTPUT:
41353ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu						if(shaderModel < 0x0300)
414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
4157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) pDst.x = o[T0 + dst.index].x;
4167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) pDst.y = o[T0 + dst.index].y;
4177551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) pDst.z = o[T0 + dst.index].z;
4187551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) pDst.w = o[T0 + dst.index].w;
419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						else
421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.rel.type == Shader::PARAMETER_VOID)   // Not relative
423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							{
4247551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.x) pDst.x = o[dst.index].x;
4257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.y) pDst.y = o[dst.index].y;
4267551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.z) pDst.z = o[dst.index].z;
4277551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.w) pDst.w = o[dst.index].w;
428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							}
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							else
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							{
431b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens								Int a = relativeAddress(dst);
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4337551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.x) pDst.x = o[dst.index + a].x;
4347551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.y) pDst.y = o[dst.index + a].y;
4357551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.z) pDst.z = o[dst.index + a].z;
4367551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens								if(dst.w) pDst.w = o[dst.index + a].w;
437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman							}
438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
4407551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_LABEL:                break;
4417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_PREDICATE: pDst = p0; break;
4427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					case Shader::PARAMETER_INPUT:                break;
443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					default:
444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						ASSERT(false);
445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
447b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens					Int4 enable = enableMask(instruction);
448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 xEnable = enable;
450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 yEnable = enable;
451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 zEnable = enable;
452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					Int4 wEnable = enable;
453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					if(predicate)
455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						unsigned char pSwizzle = instruction->predicateSwizzle;
457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
4587551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 xPredicate = p0[(pSwizzle >> 0) & 0x03];
4597551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 yPredicate = p0[(pSwizzle >> 2) & 0x03];
4607551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 zPredicate = p0[(pSwizzle >> 4) & 0x03];
4617551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						Float4 wPredicate = p0[(pSwizzle >> 6) & 0x03];
462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(!instruction->predicateNot)
464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.x) xEnable = xEnable & As<Int4>(xPredicate);
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.y) yEnable = yEnable & As<Int4>(yPredicate);
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.z) zEnable = zEnable & As<Int4>(zPredicate);
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.w) wEnable = wEnable & As<Int4>(wPredicate);
469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						else
471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.x) xEnable = xEnable & ~As<Int4>(xPredicate);
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.y) yEnable = yEnable & ~As<Int4>(yPredicate);
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.z) zEnable = zEnable & ~As<Int4>(zPredicate);
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							if(dst.w) wEnable = wEnable & ~As<Int4>(wPredicate);
476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = As<Float4>(As<Int4>(d.x) & xEnable);
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = As<Float4>(As<Int4>(d.y) & yEnable);
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = As<Float4>(As<Int4>(d.z) & zEnable);
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = As<Float4>(As<Int4>(d.w) & wEnable);
483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.x) d.x = As<Float4>(As<Int4>(d.x) | (As<Int4>(pDst.x) & ~xEnable));
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.y) d.y = As<Float4>(As<Int4>(d.y) | (As<Int4>(pDst.y) & ~yEnable));
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.z) d.z = As<Float4>(As<Int4>(d.z) | (As<Int4>(pDst.z) & ~zEnable));
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.w) d.w = As<Float4>(As<Int4>(d.w) | (As<Int4>(pDst.w) & ~wEnable));
488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				switch(dst.type)
491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_VOID:
493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_TEMP:
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(dst.rel.type == Shader::PARAMETER_VOID)
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
4977551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) r[dst.index].x = d.x;
4987551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) r[dst.index].y = d.y;
4997551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) r[dst.index].z = d.z;
5007551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) r[dst.index].w = d.w;
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					else
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
504b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens						Int a = relativeAddress(dst);
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5067551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) r[dst.index + a].x = d.x;
5077551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) r[dst.index + a].y = d.y;
5087551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) r[dst.index + a].z = d.z;
5097551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) r[dst.index + a].w = d.w;
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_ADDR:
5137551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.x) a0.x = d.x;
5147551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.y) a0.y = d.y;
5157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.z) a0.z = d.z;
5167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					if(dst.w) a0.w = d.w;
517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_RASTOUT:
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					switch(dst.index)
520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					case 0:
5227551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) o[Pos].x = d.x;
5237551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) o[Pos].y = d.y;
5247551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) o[Pos].z = d.z;
5257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) o[Pos].w = d.w;
526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					case 1:
5287551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						o[Fog].x = d.x;
529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
530b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens					case 2:
5317551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						o[Pts].y = d.x;
532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						break;
533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					default:	ASSERT(false);
534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
536b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens				case Shader::PARAMETER_ATTROUT:
537995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.x) o[C0 + dst.index].x = d.x;
538995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.y) o[C0 + dst.index].y = d.y;
539995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.z) o[C0 + dst.index].z = d.z;
540995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens					if(dst.w) o[C0 + dst.index].w = d.w;
541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::PARAMETER_TEXCRDOUT:
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			//	case Shader::PARAMETER_OUTPUT:
54453ad4afcee973b4323f84eb54c26d8329c66e51cAlexis Hetu					if(shaderModel < 0x0300)
545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
5467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.x) o[T0 + dst.index].x = d.x;
5477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.y) o[T0 + dst.index].y = d.y;
5487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.z) o[T0 + dst.index].z = d.z;
5497551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens						if(dst.w) o[T0 + dst.index].w = d.w;
550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					else
552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					{
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(dst.rel.type == Shader::PARAMETER_VOID)   // Not relative
554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						{
5557551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) o[dst.index].x = d.x;
5567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) o[dst.index].y = d.y;
5577551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) o[dst.index].z = d.z;
5587551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) o[dst.index].w = d.w;
559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						else
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
562b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens							Int a = relativeAddress(dst);
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5647551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.x) o[dst.index + a].x = d.x;
5657551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.y) o[dst.index + a].y = d.y;
5667551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.z) o[dst.index + a].z = d.z;
5677551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens							if(dst.w) o[dst.index + a].w = d.w;
568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman						}
569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					}
570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
5717551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				case Shader::PARAMETER_LABEL:             break;
5727551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				case Shader::PARAMETER_PREDICATE: p0 = d; break;
5737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				case Shader::PARAMETER_INPUT:             break;
574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				default:
575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					ASSERT(false);
576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(currentLabel != -1)
581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::setInsertBlock(returnBlock);
583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
586b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::passThrough()
587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(shader)
589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
590ec0936c46c22cfaa1d496749dfcd7c235dca825cNicolas Capens			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
59202ad0aa756ab6cbfb6ca00b98ac6793536ff9820Alexis Hetu				unsigned char usage = shader->getOutput(i, 0).usage;
593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				switch(usage)
595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				{
596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				case 0xFF:
597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					continue;
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_PSIZE:
5997551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].x;
600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_TEXCOORD:
6027551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
6037551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].y;
6047551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].z = v[i].z;
6057551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].w = v[i].w;
606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_POSITION:
6087551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
6097551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].y;
6107551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].z = v[i].z;
6117551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].w = v[i].w;
612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_COLOR:
6147551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
6157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].y = v[i].y;
6167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].z = v[i].z;
6177551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].w = v[i].w;
618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				case Shader::USAGE_FOG:
6207551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens					o[i].x = v[i].x;
621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					break;
622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				default:
623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman					ASSERT(false);
624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman				}
625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
6297551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].x = v[PositionT].x;
6307551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].y = v[PositionT].y;
6317551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].z = v[PositionT].z;
6327551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pos].w = v[PositionT].w;
633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			for(int i = 0; i < 2; i++)
635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
636995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].x = v[Color0 + i].x;
637995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].y = v[Color0 + i].y;
638995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].z = v[Color0 + i].z;
639995ddeae528ffa617a1f0bdc377f96c25a7e3887Nicolas Capens				o[C0 + i].w = v[Color0 + i].w;
640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			for(int i = 0; i < 8; i++)
643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
6447551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].x = v[TexCoord0 + i].x;
6457551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].y = v[TexCoord0 + i].y;
6467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].z = v[TexCoord0 + i].z;
6477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				o[T0 + i].w = v[TexCoord0 + i].w;
648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
6507551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			o[Pts].y = v[PointSize].x;
651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
654c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens	Vector4f VertexProgram::fetchRegister(const Src &src, unsigned int offset)
655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Vector4f reg;
6575d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		unsigned int i = src.index + offset;
658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(src.type)
660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_TEMP:
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(src.rel.type == Shader::PARAMETER_VOID)
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6647551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg = r[i];
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6682c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				reg = r[i + relativeAddress(src, src.bufferIndex)];
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_CONST:
672b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			reg = readConstant(src, offset);
67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_INPUT:
6750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			if(src.rel.type == Shader::PARAMETER_VOID)
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6777551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg = v[i];
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
6812c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				reg = v[i + relativeAddress(src, src.bufferIndex)];
68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
6830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
6847551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_VOID: return r[0];   // Dummy
68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_FLOAT4LITERAL:
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.x = Float4(src.value[0]);
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.y = Float4(src.value[1]);
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.z = Float4(src.value[2]);
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			reg.w = Float4(src.value[3]);
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
6917551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_ADDR:      reg = a0; break;
6927551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_CONSTBOOL: return r[0];   // Dummy
6937551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_CONSTINT:  return r[0];   // Dummy
6947551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_LOOP:      return r[0];   // Dummy
6957551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		case Shader::PARAMETER_PREDICATE: return r[0];   // Dummy
69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_SAMPLER:
69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(src.rel.type == Shader::PARAMETER_VOID)
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				reg.x = As<Float4>(Int4(i));
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else if(src.rel.type == Shader::PARAMETER_TEMP)
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
7037551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg.x = As<Float4>(Int4(i) + As<Int4>(r[src.rel.index].x));
70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			return reg;
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::PARAMETER_OUTPUT:
7070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			if(src.rel.type == Shader::PARAMETER_VOID)
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
7097551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				reg = o[i];
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
7132c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				reg = o[i + relativeAddress(src, src.bufferIndex)];
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
716dd8df68e64365aafe91893b11bf7cc4b67599ed4Alexis Hetu		case Shader::PARAMETER_MISCTYPE:
717877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			if(src.index == Shader::InstanceIDIndex)
718877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
719877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				reg.x = As<Float>(instanceID);
720877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
721877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			else if(src.index == Shader::VertexIDIndex)
722877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			{
723877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				reg.x = As<Float4>(vertexID);
724877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			}
725877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu			else ASSERT(false);
726dd8df68e64365aafe91893b11bf7cc4b67599ed4Alexis Hetu			return reg;
727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &x = reg[(src.swizzle >> 0) & 0x3];
73266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &y = reg[(src.swizzle >> 2) & 0x3];
73366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &z = reg[(src.swizzle >> 4) & 0x3];
73466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		const Float4 &w = reg[(src.swizzle >> 6) & 0x3];
735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman		Vector4f mod;
737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(src.modifier)
739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_NONE:
74166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = x;
74266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = y;
74366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = z;
74466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = w;
745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_NEGATE:
74766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = -x;
74866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = -y;
74966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = -z;
75066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = -w;
751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_ABS:
75366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = Abs(x);
75466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = Abs(y);
75566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = Abs(z);
75666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = Abs(w);
757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_ABS_NEGATE:
75966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = -Abs(x);
76066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = -Abs(y);
76166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = -Abs(z);
76266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = -Abs(w);
763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		case Shader::MODIFIER_NOT:
76566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.x = As<Float4>(As<Int4>(x) ^ Int4(0xFFFFFFFF));
76666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.y = As<Float4>(As<Int4>(y) ^ Int4(0xFFFFFFFF));
76766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.z = As<Float4>(As<Int4>(z) ^ Int4(0xFFFFFFFF));
76866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman			mod.w = As<Float4>(As<Int4>(w) ^ Int4(0xFFFFFFFF));
769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			break;
770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		return mod;
775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
7772c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	RValue<Pointer<Byte>> VertexProgram::uniformAddress(int bufferIndex, unsigned int index)
7782c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	{
7792c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		if(bufferIndex == -1)
7802c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		{
7812c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			return data + OFFSET(DrawData, vs.c[index]);
7822c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		}
7832c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		else
7842c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		{
7852c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			return *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, vs.u[bufferIndex])) + index;
7862c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		}
7872c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	}
7882c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
7892c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	RValue<Pointer<Byte>> VertexProgram::uniformAddress(int bufferIndex, unsigned int index, Int& offset)
7902c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	{
7912c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu		return uniformAddress(bufferIndex, index) + offset * sizeof(float4);
7922c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	}
7932c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
794b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	Vector4f VertexProgram::readConstant(const Src &src, unsigned int offset)
795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Vector4f c;
7975d96188b9c35bf896c25755e4eb97d09dcf3bed7Nicolas Capens		unsigned int i = src.index + offset;
79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(src.rel.type == Shader::PARAMETER_VOID)   // Not relative
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
8012c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i));
80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.x = c.x.xxxx;
80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.y = c.y.yyyy;
80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.z = c.z.zzzz;
80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.w = c.w.wwww;
80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
808eafdb22c36f2077815eadf2a1db0fb6547bf0241Nicolas Capens			if(shader->containsDefineInstruction())   // Constant may be known at compile time
80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
810903e025f6cd8d978f013c741431b87b04ae01fd1Alexis Hetu				for(size_t j = 0; j < shader->getLength(); j++)
81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					const Shader::Instruction &instruction = *shader->getInstruction(j);
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					if(instruction.opcode == Shader::OPCODE_DEF)
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						if(instruction.dst.index == i)
81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						{
81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.x = Float4(instruction.src[0].value[0]);
81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.y = Float4(instruction.src[0].value[1]);
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.z = Float4(instruction.src[0].value[2]);
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							c.w = Float4(instruction.src[0].value[3]);
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman							break;
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						}
82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(src.rel.type == Shader::PARAMETER_LOOP)
83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
8317551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			Int loopCounter = aL[loopDepth];
83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8332c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu			c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, loopCounter));
83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.x = c.x.xxxx;
83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.y = c.y.yyyy;
83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.z = c.z.zzzz;
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			c.w = c.w.wwww;
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(src.rel.deterministic)
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
8442c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				Int a = relativeAddress(src, src.bufferIndex);
845c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
8462c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, a));
847b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.x = c.x.xxxx;
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.y = c.y.yyyy;
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.z = c.z.zzzz;
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				c.w = c.w.wwww;
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else
85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				int component = src.rel.swizzle & 0x03;
85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Float4 a;
85719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				switch(src.rel.type)
85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
86032980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_ADDR:     a = a0[component]; break;
86132980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_TEMP:     a = r[src.rel.index][component]; break;
86232980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_INPUT:    a = v[src.rel.index][component]; break;
86332980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_OUTPUT:   a = o[src.rel.index][component]; break;
86432980acb4092207c3fa5601002f89765941ece47Nicolas Capens				case Shader::PARAMETER_CONST:    a = *Pointer<Float>(uniformAddress(src.bufferIndex, src.rel.index) + component * sizeof(float)); break;
865877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu				case Shader::PARAMETER_MISCTYPE:
866877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					if(src.rel.index == Shader::InstanceIDIndex)
867877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					{
868877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu						a = As<Float4>(Int4(instanceID)); break;
869877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					}
870877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					else if(src.rel.index == Shader::VertexIDIndex)
871877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					{
872877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu						a = As<Float4>(vertexID); break;
873877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					}
874877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					else ASSERT(false);
875877ddfc51400030afd2804a23b132ed87a2f8d2fAlexis Hetu					break;
87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				default: ASSERT(false);
87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
87819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
87902a2bb807c1e947bc99d68ba7dd4984289278be0Alexis Hetu				Int4 index = Int4(i) + As<Int4>(a) * Int4(src.rel.scale);
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
881028f41ba4d7b96e4281d69183ded014b69ab7c2cAlexis Hetu				index = Min(As<UInt4>(index), UInt4(VERTEX_UNIFORM_VECTORS));   // Clamp to constant register range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
882b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index0 = Extract(index, 0);
88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index1 = Extract(index, 1);
88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index2 = Extract(index, 2);
88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Int index3 = Extract(index, 3);
88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8882c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.x = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index0), 16);
8892c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.y = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index1), 16);
8902c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.z = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index2), 16);
8912c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu				c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, 0, index3), 16);
89219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				transpose4x4(c.x, c.y, c.z, c.w);
89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return c;
89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9002c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu	Int VertexProgram::relativeAddress(const Shader::Parameter &var, int bufferIndex)
90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		ASSERT(var.rel.deterministic);
90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(var.rel.type == Shader::PARAMETER_TEMP)
90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
9067551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return As<Int>(Extract(r[var.rel.index].x, 0)) * var.rel.scale;
90719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(var.rel.type == Shader::PARAMETER_INPUT)
90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
9107551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return As<Int>(Extract(v[var.rel.index].x, 0)) * var.rel.scale;
91119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(var.rel.type == Shader::PARAMETER_OUTPUT)
91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
9147551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return As<Int>(Extract(o[var.rel.index].x, 0)) * var.rel.scale;
91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(var.rel.type == Shader::PARAMETER_CONST)
91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
91848be735fa7eb1e2684a631cc4270a4503c7d235aAlexis Hetu			return *Pointer<Int>(uniformAddress(bufferIndex, var.rel.index)) * var.rel.scale;
91919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
920907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		else if(var.rel.type == Shader::PARAMETER_LOOP)
921907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		{
9227551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			return aL[loopDepth];
923907700d11aff5aebfbe7d003a236500109c73d49Nicolas Capens		}
92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else ASSERT(false);
92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return 0;
92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
929b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	Int4 VertexProgram::enableMask(const Shader::Instruction *instruction)
93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
9317551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF);
932b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
933d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman		if(!whileTest)
93419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
935d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			if(shader->containsBreakInstruction() && instruction->analysisBreak)
936d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			{
9377551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				enable &= enableBreak;
938d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			}
93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
940d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			if(shader->containsContinueInstruction() && instruction->analysisContinue)
941d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			{
9427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				enable &= enableContinue;
943d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			}
94419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
945d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			if(shader->containsLeaveInstruction() && instruction->analysisLeave)
946d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			{
9477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				enable &= enableLeave;
948d4ae863d01d5f448dbbba6be4ecc161971a2324fJohn Bauman			}
94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return enable;
95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
954b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M3X2(Vector4f &dst, Vector4f &src0, Src &src1)
95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
956c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
957c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot3(src0, row0);
960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot3(src0, row1);
961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
963b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M3X3(Vector4f &dst, Vector4f &src0, Src &src1)
964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
965c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
966c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
967c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot3(src0, row0);
970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot3(src0, row1);
971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot3(src0, row2);
972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
974b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M3X4(Vector4f &dst, Vector4f &src0, Src &src1)
975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
976c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
977c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
978c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
979c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row3 = fetchRegister(src1, 3);
980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot3(src0, row0);
982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot3(src0, row1);
983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot3(src0, row2);
984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.w = dot3(src0, row3);
985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
987b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M4X3(Vector4f &dst, Vector4f &src0, Src &src1)
988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
989c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
990c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
991c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot4(src0, row0);
994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot4(src0, row1);
995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot4(src0, row2);
996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
998b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::M4X4(Vector4f &dst, Vector4f &src0, Src &src1)
999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1000c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row0 = fetchRegister(src1, 0);
1001c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row1 = fetchRegister(src1, 1);
1002c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row2 = fetchRegister(src1, 2);
1003c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f row3 = fetchRegister(src1, 3);
1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.x = dot4(src0, row0);
1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.y = dot4(src0, row1);
1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.z = dot4(src0, row2);
1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		dst.w = dot4(src0, row3);
1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1011b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAK()
1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
10136d12331ad5a27e85429abf33d54d6576546fff60Nicolas Capens		enableBreak = enableBreak & ~enableStack[enableIndex];
1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1016b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control)
1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Int4 condition;
1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(control)
1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1022ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
1023ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x);  break;
1024ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
1025ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x);  break;
1026ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
1027ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x);  break;
1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1032b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		BREAK(condition);
1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1035b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAKP(const Src &predicateRegister)   // FIXME: Factor out parts common with BREAKC
1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
10377551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			condition = ~condition;
1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1044b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		BREAK(condition);
104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1047b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::BREAK(Int4 &condition)
104819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
10497551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex];
1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10517551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = enableBreak & ~condition;
1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1054b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CONTINUE()
105519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
10567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableContinue = enableContinue & ~enableStack[enableIndex];
105719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
105819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
105919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	void VertexProgram::TEST()
106019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
106119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		whileTest = true;
106219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
106319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1064b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALL(int labelIndex, int callSiteIndex)
1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!labelBlock[labelIndex])
1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
107119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(callRetBlock[labelIndex].size() > 1)
107219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
10737551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
107419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10767551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreLeave = enableLeave;
1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(labelBlock[labelIndex]);
107919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
108019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10817551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = restoreLeave;
1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1084b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALLNZ(int labelIndex, int callSiteIndex, const Src &src)
1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(src.type == Shader::PARAMETER_CONSTBOOL)
1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1088b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			CALLNZb(labelIndex, callSiteIndex, src);
1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(src.type == Shader::PARAMETER_PREDICATE)
1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1092b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			CALLNZp(labelIndex, callSiteIndex, src);
1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else ASSERT(false);
1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1097b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister)
1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
10997551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Bool condition = (*Pointer<Byte>(data + OFFSET(DrawData,vs.b[boolRegister.index])) != Byte(0));   // FIXME
1100b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
110119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(boolRegister.modifier == Shader::MODIFIER_NOT)
1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1103b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			condition = !condition;
1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(!labelBlock[labelIndex])
1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
111119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(callRetBlock[labelIndex].size() > 1)
111219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
11137551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			callStack[stackIndex++] = UInt(callSiteIndex);
111419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11167551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreLeave = enableLeave;
1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
111819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		branch(condition, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]);
111919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
112019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11217551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = restoreLeave;
1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1124b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister)
1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
11267551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
112819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			condition = ~condition;
1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11337551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex];
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		enableIndex++;
11467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[enableIndex] = condition;
11477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreLeave = enableLeave;
1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
114919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Bool notAllFalse = SignMask(condition) != 0;
115019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		branch(notAllFalse, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]);
115119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]);
1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11537551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex--;
11547551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = restoreLeave;
1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1157b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ELSE()
1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth--;
1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1161c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = ifFalseBlock[ifDepth];
1162c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(isConditionalIf[ifDepth])
1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
11667551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			Int4 condition = ~enableStack[enableIndex] & enableStack[enableIndex - 1];
116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			Bool notAllFalse = SignMask(condition) != 0;
1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			branch(notAllFalse, falseBlock, endBlock);
1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
11717551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableStack[enableIndex] = ~enableStack[enableIndex] & enableStack[enableIndex - 1];
1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createBr(endBlock);
1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::setInsertBlock(falseBlock);
1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifFalseBlock[ifDepth] = endBlock;
1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth++;
1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1184b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDIF()
1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth--;
1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1188c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = ifFalseBlock[ifDepth];
1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(endBlock);
1191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(endBlock);
1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		if(isConditionalIf[ifDepth])
1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
11957551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			enableIndex--;
1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1199b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDLOOP()
1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth--;
1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12037551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		aL[loopDepth] = aL[loopDepth] + increment[loopDepth];   // FIXME: +=
120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1205c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1206c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(endBlock);
1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12117551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth--;
12127551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1215b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDREP()
1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth--;
1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1219c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1220c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(endBlock);
1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth--;
12267551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
1227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1229b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::ENDWHILE()
123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepDepth--;
123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1233c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = loopRepTestBlock[loopRepDepth];
1234c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::createBr(testBlock);
123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(endBlock);
123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12397551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex--;
124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		whileTest = false;
124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12439aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	void VertexProgram::ENDSWITCH()
12449aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	{
12459aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepDepth--;
12469aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1247c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
1248ec0936c46c22cfaa1d496749dfcd7c235dca825cNicolas Capens
1249ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		Nucleus::createBr(endBlock);
12509aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		Nucleus::setInsertBlock(endBlock);
12519aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	}
12529aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1253b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IF(const Src &src)
1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
125519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(src.type == Shader::PARAMETER_CONSTBOOL)
1256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1257b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			IFb(src);
1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
125919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else if(src.type == Shader::PARAMETER_PREDICATE)
1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1261b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			IFp(src);
1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
126319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else
126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
1265c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Int4 condition = As<Int4>(fetchRegister(src).x);
1266b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens			IF(condition);
126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1270b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IFb(const Src &boolRegister)
1271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ASSERT(ifDepth < 24 + 4);
1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
12747551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Bool condition = (*Pointer<Byte>(data + OFFSET(DrawData,vs.b[boolRegister.index])) != Byte(0));   // FIXME
1275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
127619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(boolRegister.modifier == Shader::MODIFIER_NOT)
1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			condition = !condition;
1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1281c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *trueBlock = Nucleus::createBasicBlock();
1282c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = Nucleus::createBasicBlock();
1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		branch(condition, trueBlock, falseBlock);
1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		isConditionalIf[ifDepth] = false;
1287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifFalseBlock[ifDepth] = falseBlock;
1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth++;
1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1292b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IFp(const Src &predicateRegister)
1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
12947551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 condition = As<Int4>(p0[predicateRegister.swizzle & 0x3]);
1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
129619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(predicateRegister.modifier == Shader::MODIFIER_NOT)
1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			condition = ~condition;
1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1301b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		IF(condition);
1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1304b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IFC(Vector4f &src0, Vector4f &src1, Control control)
1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Int4 condition;
1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		switch(control)
1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1310ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
1311ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x);  break;
1312ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
1313ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x);  break;
1314ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
1315ac6d50501fc0b54dcfb995e466cb1fe5fc86991eNicolas Capens		case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x);  break;
1316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		default:
1317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			ASSERT(false);
1318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1320b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens		IF(condition);
132119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
132219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1323b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::IF(Int4 &condition)
132419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
13257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex];
1326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13277551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex++;
13287551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[enableIndex] = condition;
1329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1330c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *trueBlock = Nucleus::createBasicBlock();
1331c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *falseBlock = Nucleus::createBasicBlock();
1332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Bool notAllFalse = SignMask(condition) != 0;
1334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		branch(notAllFalse, trueBlock, falseBlock);
1336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		isConditionalIf[ifDepth] = true;
1338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifFalseBlock[ifDepth] = falseBlock;
1339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		ifDepth++;
1341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	void VertexProgram::LABEL(int labelIndex)
1344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(!labelBlock[labelIndex])
134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			labelBlock[labelIndex] = Nucleus::createBasicBlock();
134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(labelBlock[labelIndex]);
135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		currentLabel = labelIndex;
1352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1354b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::LOOP(const Src &integerRegister)
1355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
13567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth++;
1357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13587551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][0]));
13597551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		aL[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][1]));
13607551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		increment[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][2]));
1361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		// FIXME: Compiles to two instructions?
13637551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		If(increment[loopDepth] == 0)
1364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
13657551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens			increment[loopDepth] = 1;
1366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1368c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1369c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1370c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepTestBlock[loopRepDepth] = testBlock;
1373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepEndBlock[loopRepDepth] = endBlock;
1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		// FIXME: jump(testBlock)
1376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(testBlock);
1378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13797551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		branch(iteration[loopDepth] > 0, loopBlock, endBlock);
1380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(loopBlock);
1381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13827551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = iteration[loopDepth] - 1;   // FIXME: --
1383b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
1384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth++;
1385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1387b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::REP(const Src &integerRegister)
1388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
13897551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		loopDepth++;
1390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13917551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = *Pointer<Int>(data + OFFSET(DrawData,vs.i[integerRegister.index][0]));
13927551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		aL[loopDepth] = aL[loopDepth - 1];
1393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1394c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1395c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1396c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepTestBlock[loopRepDepth] = testBlock;
1399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepEndBlock[loopRepDepth] = endBlock;
1400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		// FIXME: jump(testBlock)
1402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::createBr(testBlock);
1403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(testBlock);
1404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14057551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		branch(iteration[loopDepth] > 0, loopBlock, endBlock);
1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		Nucleus::setInsertBlock(loopBlock);
1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14087551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		iteration[loopDepth] = iteration[loopDepth] - 1;   // FIXME: --
1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		loopRepDepth++;
1411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1413b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::WHILE(const Src &temporaryRegister)
141419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
14157551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableIndex++;
141619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1417c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *loopBlock = Nucleus::createBasicBlock();
1418c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *testBlock = Nucleus::createBasicBlock();
1419c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
1420b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
142119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepTestBlock[loopRepDepth] = testBlock;
142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepEndBlock[loopRepDepth] = endBlock;
142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14247551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreBreak = enableBreak;
14257551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		Int4 restoreContinue = enableContinue;
142619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1427d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		// TODO: jump(testBlock)
142819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::createBr(testBlock);
142919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(testBlock);
14307551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableContinue = restoreContinue;
143119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1432c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		const Vector4f &src = fetchRegister(temporaryRegister);
143319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Int4 condition = As<Int4>(src.x);
14347551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		condition &= enableStack[enableIndex - 1];
14352ff2948b730812543a6d0702377084c472e3404dNicolas Capens		if(shader->containsLeaveInstruction()) condition &= enableLeave;
14366d12331ad5a27e85429abf33d54d6576546fff60Nicolas Capens		if(shader->containsBreakInstruction()) condition &= enableBreak;
14377551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableStack[enableIndex] = condition;
143819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Bool notAllFalse = SignMask(condition) != 0;
144019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		branch(notAllFalse, loopBlock, endBlock);
1441b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(endBlock);
14437551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableBreak = restoreBreak;
1444b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		Nucleus::setInsertBlock(loopBlock);
144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		loopRepDepth++;
144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
14499aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
14509aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	void VertexProgram::SWITCH()
14519aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	{
1452c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens		BasicBlock *endBlock = Nucleus::createBasicBlock();
14539aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
14549aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepTestBlock[loopRepDepth] = nullptr;
14559aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepEndBlock[loopRepDepth] = endBlock;
14569aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu
1457d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		Int4 restoreBreak = enableBreak;
1458d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
1459d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		BasicBlock *currentBlock = Nucleus::getInsertBlock();
1460d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
1461d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		Nucleus::setInsertBlock(endBlock);
1462d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		enableBreak = restoreBreak;
1463d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
1464d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens		Nucleus::setInsertBlock(currentBlock);
1465d6bcc11172ba569e22147c09e650b840eb7ab76dNicolas Capens
14669aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu		loopRepDepth++;
14679aa83a93a06e1cf09547716d92f3ca82010dcf43Alexis Hetu	}
146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1469b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::RET()
1470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
147119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(currentLabel == -1)
1472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			returnBlock = Nucleus::createBasicBlock();
1474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createBr(returnBlock);
1475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		else
1477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		{
1478c8b67a48e64ca05fbecfcd9990d16e1cb68a9578Nicolas Capens			BasicBlock *unreachableBlock = Nucleus::createBasicBlock();
1479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
148019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if(callRetBlock[currentLabel].size() > 1)   // Pop the return destination from the call stack
1481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			{
148219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				// FIXME: Encapsulate
14837551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens				UInt index = callStack[--stackIndex];
1484b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
14851933654b62251805d4575b05b6829275b0fe6142Nicolas Capens				Value *value = index.loadValue();
1486b98fe5cd1eaa821083d816cf86a20eefe22f57c7Nicolas Capens				SwitchCases *switchCases = Nucleus::createSwitch(value, unreachableBlock, (int)callRetBlock[currentLabel].size());
148719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
148819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				for(unsigned int i = 0; i < callRetBlock[currentLabel].size(); i++)
148919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
1490b98fe5cd1eaa821083d816cf86a20eefe22f57c7Nicolas Capens					Nucleus::addSwitchCase(switchCases, i, callRetBlock[currentLabel][i]);
149119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
149219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
149319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else if(callRetBlock[currentLabel].size() == 1)   // Jump directly to the unique return destination
149419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
149519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Nucleus::createBr(callRetBlock[currentLabel][0]);
149619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
149719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			else   // Function isn't called
149819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
149919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				Nucleus::createBr(unreachableBlock);
1500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			}
1501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::setInsertBlock(unreachableBlock);
1503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman			Nucleus::createUnreachable();
1504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman		}
1505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
1506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1507b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::LEAVE()
1508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	{
15097551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens		enableLeave = enableLeave & ~enableStack[enableIndex];
151019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
151119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// FIXME: Return from function if all instances left
151219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		// FIXME: Use enableLeave in other control-flow constructs
151319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
1514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1515a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1)
151619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
1517a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), (src0), Base);
151819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
1519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1520a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
152119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
1522a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Base, Offset});
1523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman	}
152419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1525a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
152625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1527a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
152825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
152925d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1530a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
153125d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1532a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
153325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
153425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1535a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
153625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1537a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
153825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
153925d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1540a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
154125d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1542a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
154325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
154425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1545a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
154625d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1547a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, src0, Grad);
154825d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
154925d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1550a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	void VertexProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
155125d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	{
1552a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
155325d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu	}
155425d47fc9eb8e8aaf864fab0d6aa7305d034d807bAlexis Hetu
1555b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens	void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
15569bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu	{
1557da163edbdc41cbccacfd526f51b2cd2a9b6267bfAlexis Hetu		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + src1.index * sizeof(Texture);
155889a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		dst = SamplerCore::textureSize(texture, lod);
15599bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu	}
15609bcb31da0cf95258949da1bb697f3981a70c476bAlexis Hetu
1561a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	Vector4f VertexProgram::sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
156219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{
1563c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		Vector4f tmp;
1564c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
156519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID)
156619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
1567a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens			tmp = sampleTexture(s.index, uvwq, lod, dsx, dsy, offset, function);
156819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
156919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		else
157019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		{
1571c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			Int index = As<Int>(Float(fetchRegister(s).x.x));
157219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1573c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens			for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
157419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			{
157519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				if(shader->usesSampler(i))
157619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				{
157719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					If(index == i)
157819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					{
1579a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens						tmp = sampleTexture(i, uvwq, lod, dsx, dsy, offset, function);
158019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman						// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
158119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman					}
158219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				}
158319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			}
158419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		}
1585c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
158689a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		Vector4f c;
1587c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.x = tmp[(s.swizzle >> 0) & 0x3];
1588c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.y = tmp[(s.swizzle >> 2) & 0x3];
1589c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.z = tmp[(s.swizzle >> 4) & 0x3];
1590c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens		c.w = tmp[(s.swizzle >> 6) & 0x3];
159189a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens
159289a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		return c;
159389a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens	}
159489a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens
1595a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens	Vector4f VertexProgram::sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
159689a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens	{
159789a218b476e290a0e42e3fd23d913333ec0e5847Nicolas Capens		Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + sampler * sizeof(Texture);
1598a0b5783f31ffec2eef21548ce04cbc447d22148cNicolas Capens		return SamplerCore(constants, state.sampler[sampler]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, lod, dsx, dsy, offset, function);
159919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
1600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1601