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