VertexProgram.cpp revision 66b8ab22586debccb1f787d4d52b7f042d4ddeb8
1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// SwiftShader Software Renderer 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Copyright(c) 2005-2012 TransGaming Inc. 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// All rights reserved. No part of this software may be copied, distributed, transmitted, 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// transcribed, stored in a retrieval system, translated into any human or computer 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// language by any means, or disclosed to third parties without the explicit written 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// or implied, including but not limited to any patent rights, are granted to you. 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "VertexProgram.hpp" 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Renderer.hpp" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "VertexShader.hpp" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Vertex.hpp" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Half.hpp" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SamplerCore.hpp" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Debug.hpp" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanextern bool localShaderConstants; 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace sw 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VertexProgram::VertexProgram(const VertexProcessor::State &state, const VertexShader *shader) : VertexRoutine(state, shader) 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifDepth = 0; 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepDepth = 0; 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman breakDepth = 0; 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman currentLabel = -1; 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman whileTest = false; 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < 2048; i++) 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman labelBlock[i] = 0; 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VertexProgram::~VertexProgram() 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < 4; i++) 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete sampler[i]; 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::pipeline(Registers &r) 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < 4; i++) 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sampler[i] = new SamplerCore(r.constants, state.samplerState[i]); 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(!state.preTransformed) 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman program(r); 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman passThrough(r); 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::program(Registers &r) 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // shader->print("VertexShader-%0.8X.txt", state.shaderID); 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned short version = shader->getVersion(); 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex = 0; 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.stackIndex = 0; 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Create all call site return blocks up front 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for(int i = 0; i < shader->getLength(); i++) 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Shader::Instruction *instruction = shader->getInstruction(i); 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Shader::Opcode opcode = instruction->opcode; 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(opcode == Shader::OPCODE_CALL || opcode == Shader::OPCODE_CALLNZ) 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Dst &dst = instruction->dst; 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ASSERT(callRetBlock[dst.label].size() == dst.callSite); 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman callRetBlock[dst.label].push_back(Nucleus::createBasicBlock()); 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for(int i = 0; i < shader->getLength(); i++) 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Shader::Instruction *instruction = shader->getInstruction(i); 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Shader::Opcode opcode = instruction->opcode; 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(opcode == Shader::OPCODE_DCL || opcode == Shader::OPCODE_DEF || opcode == Shader::OPCODE_DEFI || opcode == Shader::OPCODE_DEFB) 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Dst dst = instruction->dst; 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Src src0 = instruction->src[0]; 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Src src1 = instruction->src[1]; 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Src src2 = instruction->src[2]; 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool predicate = instruction->predicate; 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int size = shader->size(opcode); 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Usage usage = instruction->usage; 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned char usageIndex = instruction->usageIndex; 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Control control = instruction->control; 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool integer = dst.type == Shader::PARAMETER_ADDR; 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool pp = dst.partialPrecision; 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f d; 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f s0; 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f s1; 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f s2; 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src0.type != Shader::PARAMETER_VOID) s0 = reg(r, src0); 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src1.type != Shader::PARAMETER_VOID) s1 = reg(r, src1); 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src2.type != Shader::PARAMETER_VOID) s2 = reg(r, src2); 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(opcode) 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_1_0: break; 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_1_1: break; 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_2_0: break; 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_2_x: break; 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_2_sw: break; 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_3_0: break; 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_VS_3_sw: break; 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DCL: break; 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DEF: break; 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DEFI: break; 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DEFB: break; 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_NOP: break; 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ABS: abs(d, s0); break; 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ADD: add(d, s0, s1); break; 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_CRS: crs(d, s0, s1); break; 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_FORWARD1: forward1(d, s0, s1, s2); break; 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_FORWARD2: forward2(d, s0, s1, s2); break; 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_FORWARD3: forward3(d, s0, s1, s2); break; 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_FORWARD4: forward4(d, s0, s1, s2); break; 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFLECT1: reflect1(d, s0, s1); break; 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFLECT2: reflect2(d, s0, s1); break; 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFLECT3: reflect3(d, s0, s1); break; 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFLECT4: reflect4(d, s0, s1); break; 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFRACT1: refract1(d, s0, s1, s2.x); break; 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFRACT2: refract2(d, s0, s1, s2.x); break; 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFRACT3: refract3(d, s0, s1, s2.x); break; 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REFRACT4: refract4(d, s0, s1, s2.x); break; 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DP1: dp1(d, s0, s1); break; 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DP2: dp2(d, s0, s1); break; 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DP3: dp3(d, s0, s1); break; 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DP4: dp4(d, s0, s1); break; 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ATT: att(d, s0, s1); break; 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_EXP2X: exp2x(d, s0, pp); break; 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_EXP2: exp2(d, s0, pp); break; 15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_EXPP: expp(d, s0, version); break; 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_EXP: exp(d, s0, pp); break; 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_FRC: frc(d, s0); break; 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_TRUNC: trunc(d, s0); break; 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_FLOOR: floor(d, s0); break; 16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_CEIL: ceil(d, s0); break; 16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LIT: lit(d, s0); break; 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LOG2X: log2x(d, s0, pp); break; 16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LOG2: log2(d, s0, pp); break; 16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LOGP: logp(d, s0, version); break; 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LOG: log(d, s0, pp); break; 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LRP: lrp(d, s0, s1, s2); break; 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_STEP: step(d, s0, s1); break; 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SMOOTH: smooth(d, s0, s1, s2); break; 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_M3X2: M3X2(r, d, s0, src1); break; 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_M3X3: M3X3(r, d, s0, src1); break; 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_M3X4: M3X4(r, d, s0, src1); break; 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_M4X3: M4X3(r, d, s0, src1); break; 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_M4X4: M4X4(r, d, s0, src1); break; 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MAD: mad(d, s0, s1, s2); break; 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MAX: max(d, s0, s1); break; 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MIN: min(d, s0, s1); break; 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MOV: mov(d, s0, integer); break; 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MOVA: mov(d, s0); break; 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_F2B: f2b(d, s0); break; 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_B2F: b2f(d, s0); break; 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MUL: mul(d, s0, s1); break; 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_NRM2: nrm2(d, s0, pp); break; 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_NRM3: nrm3(d, s0, pp); break; 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_NRM4: nrm4(d, s0, pp); break; 18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_POWX: powx(d, s0, s1, pp); break; 18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_POW: pow(d, s0, s1, pp); break; 18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_RCPX: rcpx(d, s0, pp); break; 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DIV: div(d, s0, s1); break; 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_MOD: mod(d, s0, s1); break; 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_RSQX: rsqx(d, s0, pp); break; 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SQRT: sqrt(d, s0, pp); break; 19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_RSQ: rsq(d, s0, pp); break; 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LEN2: len2(d.x, s0, pp); break; 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LEN3: len3(d.x, s0, pp); break; 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LEN4: len4(d.x, s0, pp); break; 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DIST1: dist1(d.x, s0, s1, pp); break; 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DIST2: dist2(d.x, s0, s1, pp); break; 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DIST3: dist3(d.x, s0, s1, pp); break; 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DIST4: dist4(d.x, s0, s1, pp); break; 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SGE: step(d, s1, s0); break; 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SGN: sgn(d, s0); break; 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SINCOS: sincos(d, s0, pp); break; 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_COS: cos(d, s0, pp); break; 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SIN: sin(d, s0, pp); break; 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_TAN: tan(d, s0); break; 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ACOS: acos(d, s0); break; 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ASIN: asin(d, s0); break; 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ATAN: atan(d, s0); break; 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ATAN2: atan2(d, s0, s1); break; 21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SLT: slt(d, s0, s1); break; 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SUB: sub(d, s0, s1); break; 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_BREAK: BREAK(r); break; 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_BREAKC: BREAKC(r, s0, s1, control); break; 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_BREAKP: BREAKP(r, src0); break; 21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_CONTINUE: CONTINUE(r); break; 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_TEST: TEST(); break; 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_CALL: CALL(r, dst.label, dst.callSite); break; 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_CALLNZ: CALLNZ(r, dst.label, dst.callSite, src0); break; 22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ELSE: ELSE(r); break; 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ENDIF: ENDIF(r); break; 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ENDLOOP: ENDLOOP(r); break; 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ENDREP: ENDREP(r); break; 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ENDWHILE: ENDWHILE(r); break; 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_IF: IF(r, src0); break; 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_IFC: IFC(r, s0, s1, control); break; 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LABEL: LABEL(dst.index); break; 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LOOP: LOOP(r, src1); break; 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_REP: REP(r, src0); break; 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_WHILE: WHILE(r, src0); break; 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_RET: RET(r); break; 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_LEAVE: LEAVE(r); break; 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_CMP: cmp(d, s0, s1, control); break; 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ICMP: icmp(d, s0, s1, control); break; 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_SELECT: select(d, s0, s1, s2); break; 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_EXTRACT: extract(d.x, s0, s1.x); break; 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_INSERT: insert(d, s0, s1.x, s2.x); break; 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ALL: all(d.x, s0); break; 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_ANY: any(d.x, s0); break; 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_NOT: not(d, s0); break; 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_OR: or(d.x, s0.x, s1.x); break; 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_XOR: xor(d.x, s0.x, s1.x); break; 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_AND: and(d.x, s0.x, s1.x); break; 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_TEXLDL: TEXLDL(r, d, s0, src1); break; 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_TEX: TEX(r, d, s0, src1); break; 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_END: break; 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.type != Shader::PARAMETER_VOID && dst.type != Shader::PARAMETER_LABEL && opcode != Shader::OPCODE_NOP) 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.integer) 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(opcode) 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::OPCODE_DIV: 25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) d.x = Trunc(d.x); 25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) d.y = Trunc(d.y); 26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) d.z = Trunc(d.z); 26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) d.w = Trunc(d.w); 26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; // No truncation to integer required when arguments are integer 26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.saturate) 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) d.x = Max(d.x, Float4(0.0f)); 27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) d.y = Max(d.y, Float4(0.0f)); 27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) d.z = Max(d.z, Float4(0.0f)); 27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) d.w = Max(d.w, Float4(0.0f)); 27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) d.x = Min(d.x, Float4(1.0f)); 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) d.y = Min(d.y, Float4(1.0f)); 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) d.z = Min(d.z, Float4(1.0f)); 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) d.w = Min(d.w, Float4(1.0f)); 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(shader->containsDynamicBranching()) 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f pDst; // FIXME: Rename 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(dst.type) 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_VOID: break; 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_TEMP: 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.rel.type == Shader::PARAMETER_VOID) 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.r[dst.index].x; 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.r[dst.index].y; 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.r[dst.index].z; 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.r[dst.index].w; 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int a = relativeAddress(r, dst); 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.r[dst.index + a].x; 30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.r[dst.index + a].y; 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.r[dst.index + a].z; 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.r[dst.index + a].w; 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_ADDR: pDst = r.a0; break; 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_RASTOUT: 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(dst.index) 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 0: 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.o[Pos].x; 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.o[Pos].y; 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.o[Pos].z; 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.o[Pos].w; 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 1: 31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pDst.x = r.o[Fog].x; 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 2: 32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pDst.x = r.o[Pts].y; 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_ATTROUT: 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.o[D0 + dst.index].x; 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.o[D0 + dst.index].y; 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.o[D0 + dst.index].z; 33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.o[D0 + dst.index].w; 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_TEXCRDOUT: 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // case Shader::PARAMETER_OUTPUT: 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(version < 0x0300) 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.o[T0 + dst.index].x; 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.o[T0 + dst.index].y; 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.o[T0 + dst.index].z; 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.o[T0 + dst.index].w; 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.rel.type == Shader::PARAMETER_VOID) // Not relative 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.o[dst.index].x; 34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.o[dst.index].y; 34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.o[dst.index].z; 34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.o[dst.index].w; 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(dst.rel.type == Shader::PARAMETER_LOOP) 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int aL = r.aL[r.loopDepth]; 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.o[dst.index + aL].x; 35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.o[dst.index + aL].y; 35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.o[dst.index + aL].z; 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.o[dst.index + aL].w; 35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int a = relativeAddress(r, dst); 36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) pDst.x = r.o[dst.index + a].x; 36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) pDst.y = r.o[dst.index + a].y; 36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) pDst.z = r.o[dst.index + a].z; 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) pDst.w = r.o[dst.index + a].w; 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_LABEL: break; 37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_PREDICATE: pDst = r.p0; break; 37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_INPUT: break; 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 enable = enableMask(r, instruction); 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 xEnable = enable; 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 yEnable = enable; 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 zEnable = enable; 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 wEnable = enable; 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(predicate) 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned char pSwizzle = instruction->predicateSwizzle; 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Float4 xPredicate = r.p0[(pSwizzle >> 0) & 0x03]; 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Float4 yPredicate = r.p0[(pSwizzle >> 2) & 0x03]; 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Float4 zPredicate = r.p0[(pSwizzle >> 4) & 0x03]; 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Float4 wPredicate = r.p0[(pSwizzle >> 6) & 0x03]; 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(!instruction->predicateNot) 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) xEnable = xEnable & As<Int4>(xPredicate); 39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) yEnable = yEnable & As<Int4>(yPredicate); 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) zEnable = zEnable & As<Int4>(zPredicate); 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) wEnable = wEnable & As<Int4>(wPredicate); 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) xEnable = xEnable & ~As<Int4>(xPredicate); 40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) yEnable = yEnable & ~As<Int4>(yPredicate); 40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) zEnable = zEnable & ~As<Int4>(zPredicate); 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) wEnable = wEnable & ~As<Int4>(wPredicate); 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) d.x = As<Float4>(As<Int4>(d.x) & xEnable); 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) d.y = As<Float4>(As<Int4>(d.y) & yEnable); 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) d.z = As<Float4>(As<Int4>(d.z) & zEnable); 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) d.w = As<Float4>(As<Int4>(d.w) & wEnable); 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) d.x = As<Float4>(As<Int4>(d.x) | (As<Int4>(pDst.x) & ~xEnable)); 41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) d.y = As<Float4>(As<Int4>(d.y) | (As<Int4>(pDst.y) & ~yEnable)); 41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) d.z = As<Float4>(As<Int4>(d.z) | (As<Int4>(pDst.z) & ~zEnable)); 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) d.w = As<Float4>(As<Int4>(d.w) | (As<Int4>(pDst.w) & ~wEnable)); 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(dst.type) 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_VOID: 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_TEMP: 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.rel.type == Shader::PARAMETER_VOID) 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.r[dst.index].x = d.x; 42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.r[dst.index].y = d.y; 42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.r[dst.index].z = d.z; 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.r[dst.index].w = d.w; 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int a = relativeAddress(r, dst); 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.r[dst.index + a].x = d.x; 43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.r[dst.index + a].y = d.y; 43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.r[dst.index + a].z = d.z; 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.r[dst.index + a].w = d.w; 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_ADDR: 44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.a0.x = d.x; 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.a0.y = d.y; 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.a0.z = d.z; 44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.a0.w = d.w; 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_RASTOUT: 44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(dst.index) 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 0: 45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.o[Pos].x = d.x; 45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.o[Pos].y = d.y; 45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.o[Pos].z = d.z; 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.o[Pos].w = d.w; 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 1: 45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[Fog].x = d.x; 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 2: 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[Pts].y = d.x; 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: ASSERT(false); 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_ATTROUT: 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.o[D0 + dst.index].x = d.x; 46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.o[D0 + dst.index].y = d.y; 46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.o[D0 + dst.index].z = d.z; 47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.o[D0 + dst.index].w = d.w; 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_TEXCRDOUT: 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // case Shader::PARAMETER_OUTPUT: 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(version < 0x0300) 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.o[T0 + dst.index].x = d.x; 47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.o[T0 + dst.index].y = d.y; 47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.o[T0 + dst.index].z = d.z; 47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.o[T0 + dst.index].w = d.w; 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.rel.type == Shader::PARAMETER_VOID) // Not relative 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.o[dst.index].x = d.x; 48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.o[dst.index].y = d.y; 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.o[dst.index].z = d.z; 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.o[dst.index].w = d.w; 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(dst.rel.type == Shader::PARAMETER_LOOP) 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int aL = r.aL[r.loopDepth]; 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.o[dst.index + aL].x = d.x; 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.o[dst.index + aL].y = d.y; 49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.o[dst.index + aL].z = d.z; 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.o[dst.index + aL].w = d.w; 49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int a = relativeAddress(r, dst); 50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.x) r.o[dst.index + a].x = d.x; 50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.y) r.o[dst.index + a].y = d.y; 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.z) r.o[dst.index + a].z = d.z; 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(dst.w) r.o[dst.index + a].w = d.w; 507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_LABEL: break; 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_PREDICATE: r.p0 = d; break; 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_INPUT: break; 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(currentLabel != -1) 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(returnBlock); 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::passThrough(Registers &r) 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(shader) 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < 12; i++) 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned char usage = shader->output[i][0].usage; 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned char index = shader->output[i][0].index; 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(usage) 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 0xFF: 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::USAGE_PSIZE: 53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].y = r.v[i].x; 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::USAGE_TEXCOORD: 54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].x = r.v[i].x; 54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].y = r.v[i].y; 54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].z = r.v[i].z; 54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].w = r.v[i].w; 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::USAGE_POSITION: 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].x = r.v[i].x; 54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].y = r.v[i].y; 55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].z = r.v[i].z; 55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].w = r.v[i].w; 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::USAGE_COLOR: 55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].x = r.v[i].x; 55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].y = r.v[i].y; 55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].z = r.v[i].z; 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].w = r.v[i].w; 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::USAGE_FOG: 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[i].x = r.v[i].x; 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[Pos].x = r.v[PositionT].x; 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[Pos].y = r.v[PositionT].y; 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[Pos].z = r.v[PositionT].z; 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[Pos].w = r.v[PositionT].w; 573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < 2; i++) 575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[D0 + i].x = r.v[Color0 + i].x; 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[D0 + i].y = r.v[Color0 + i].y; 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[D0 + i].z = r.v[Color0 + i].z; 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[D0 + i].w = r.v[Color0 + i].w; 580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < 8; i++) 583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[T0 + i].x = r.v[TexCoord0 + i].x; 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[T0 + i].y = r.v[TexCoord0 + i].y; 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[T0 + i].z = r.v[TexCoord0 + i].z; 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.o[T0 + i].w = r.v[TexCoord0 + i].w; 588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman r.o[Pts].y = r.v[PointSize].x; 591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f VertexProgram::reg(Registers &r, const Src &src, int offset) 595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int i = src.index + offset; 597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f reg; 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(src.type) 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_TEMP: 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.rel.type == Shader::PARAMETER_VOID) 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = r.r[i]; 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = r.r[i + relativeAddress(r, src)]; 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_CONST: 61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = readConstant(r, src, offset); 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_INPUT: 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.rel.type == Shader::PARAMETER_VOID) 61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = r.v[i]; 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = r.v[i + relativeAddress(r, src)]; 62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_VOID: return r.r[0]; // Dummy 62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_FLOAT4LITERAL: 62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg.x = Float4(src.value[0]); 62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg.y = Float4(src.value[1]); 62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg.z = Float4(src.value[2]); 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg.w = Float4(src.value[3]); 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_ADDR: reg = r.a0; break; 63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_CONSTBOOL: return r.r[0]; // Dummy 63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_CONSTINT: return r.r[0]; // Dummy 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_LOOP: return r.r[0]; // Dummy 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_PREDICATE: return r.r[0]; // Dummy 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_SAMPLER: 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.rel.type == Shader::PARAMETER_VOID) 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg.x = As<Float4>(Int4(i)); 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(src.rel.type == Shader::PARAMETER_TEMP) 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg.x = As<Float4>(Int4(i) + RoundInt(r.r[src.rel.index].x)); 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return reg; 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_OUTPUT: 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.rel.type == Shader::PARAMETER_VOID) 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = r.o[i]; 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman reg = r.o[i + relativeAddress(r, src)]; 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 66166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Float4 &x = reg[(src.swizzle >> 0) & 0x3]; 66266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Float4 &y = reg[(src.swizzle >> 2) & 0x3]; 66366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Float4 &z = reg[(src.swizzle >> 4) & 0x3]; 66466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Float4 &w = reg[(src.swizzle >> 6) & 0x3]; 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 66666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Vector4f mod; 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(src.modifier) 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::MODIFIER_NONE: 67166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.x = x; 67266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.y = y; 67366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.z = z; 67466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.w = w; 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::MODIFIER_NEGATE: 67766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.x = -x; 67866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.y = -y; 67966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.z = -z; 68066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.w = -w; 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::MODIFIER_ABS: 68366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.x = Abs(x); 68466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.y = Abs(y); 68566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.z = Abs(z); 68666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.w = Abs(w); 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::MODIFIER_ABS_NEGATE: 68966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.x = -Abs(x); 69066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.y = -Abs(y); 69166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.z = -Abs(z); 69266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.w = -Abs(w); 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::MODIFIER_NOT: 69566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.x = As<Float4>(As<Int4>(x) ^ Int4(0xFFFFFFFF)); 69666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.y = As<Float4>(As<Int4>(y) ^ Int4(0xFFFFFFFF)); 69766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.z = As<Float4>(As<Int4>(z) ^ Int4(0xFFFFFFFF)); 69866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman mod.w = As<Float4>(As<Int4>(w) ^ Int4(0xFFFFFFFF)); 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return mod; 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f VertexProgram::readConstant(Registers &r, const Src &src, int offset) 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f c; 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int i = src.index + offset; 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.rel.type == Shader::PARAMETER_VOID) // Not relative 71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = c.y = c.z = c.w = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c[i])); 71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = c.x.xxxx; 71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.y = c.y.yyyy; 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.z = c.z.zzzz; 72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.w = c.w.wwww; 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(localShaderConstants) // Constant may be known at compile time 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for(int j = 0; j < shader->getLength(); j++) 72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Shader::Instruction &instruction = *shader->getInstruction(j); 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(instruction.opcode == Shader::OPCODE_DEF) 72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(instruction.dst.index == i) 73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = Float4(instruction.src[0].value[0]); 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.y = Float4(instruction.src[0].value[1]); 73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.z = Float4(instruction.src[0].value[2]); 73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.w = Float4(instruction.src[0].value[3]); 73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(src.rel.type == Shader::PARAMETER_LOOP) 74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int loopCounter = r.aL[r.loopDepth]; 74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = c.y = c.z = c.w = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c[i]) + loopCounter * 16); 74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = c.x.xxxx; 75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.y = c.y.yyyy; 75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.z = c.z.zzzz; 75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.w = c.w.wwww; 75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.rel.deterministic) 75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int a = relativeAddress(r, src); 75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = c.y = c.z = c.w = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c[i]) + a * 16); 76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = c.x.xxxx; 76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.y = c.y.yyyy; 76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.z = c.z.zzzz; 76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.w = c.w.wwww; 76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int component = src.rel.swizzle & 0x03; 77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Float4 a; 77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(src.rel.type) 77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_ADDR: a = r.a0[component]; break; 77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_TEMP: a = r.r[src.rel.index][component]; break; 77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_INPUT: a = r.v[src.rel.index][component]; break; 77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::PARAMETER_OUTPUT: a = r.o[src.rel.index][component]; break; 77866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman case Shader::PARAMETER_CONST: a = *Pointer<Float>(r.data + OFFSET(DrawData,vs.c[src.rel.index][component])); break; 77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: ASSERT(false); 78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 index = Int4(i) + RoundInt(a) * Int4(src.rel.scale); 78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman index = Min(As<UInt4>(index), UInt4(256)); // Clamp to constant register range, c[256] = {0, 0, 0, 0} 78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int index0 = Extract(index, 0); 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int index1 = Extract(index, 1); 78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int index2 = Extract(index, 2); 78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int index3 = Extract(index, 3); 79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.x = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c) + index0 * 16, 16); 79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.y = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c) + index1 * 16, 16); 79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.z = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c) + index2 * 16, 16); 79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman c.w = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c) + index3 * 16, 16); 79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman transpose4x4(c.x, c.y, c.z, c.w); 79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return c; 80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int VertexProgram::relativeAddress(Registers &r, const Shader::Parameter &var) 80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ASSERT(var.rel.deterministic); 80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(var.rel.type == Shader::PARAMETER_TEMP) 80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RoundInt(Extract(r.r[var.rel.index].x, 0)) * var.rel.scale; 81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(var.rel.type == Shader::PARAMETER_INPUT) 81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RoundInt(Extract(r.v[var.rel.index].x, 0)) * var.rel.scale; 81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(var.rel.type == Shader::PARAMETER_OUTPUT) 81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RoundInt(Extract(r.o[var.rel.index].x, 0)) * var.rel.scale; 81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(var.rel.type == Shader::PARAMETER_CONST) 82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RValue<Float4> c = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c[var.rel.index])); 82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RoundInt(Extract(c, 0)) * var.rel.scale; 82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else ASSERT(false); 82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 VertexProgram::enableMask(Registers &r, const Shader::Instruction *instruction) 83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 enable = instruction->analysisBranch ? Int4(r.enableStack[r.enableIndex]) : Int4(0xFFFFFFFF); 83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(shader->containsBreakInstruction() && !whileTest && instruction->analysisBreak) 83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman enable &= r.enableBreak; 83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(shader->containsContinueInstruction() && !whileTest && instruction->analysisContinue) 84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman enable &= r.enableContinue; 84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(shader->containsLeaveInstruction() && instruction->analysisLeave) 84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman enable &= r.enableLeave; 84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return enable; 85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::M3X2(Registers &r, Vector4f &dst, Vector4f &src0, Src &src1) 85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row0 = reg(r, src1, 0); 85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row1 = reg(r, src1, 1); 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.x = dot3(src0, row0); 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.y = dot3(src0, row1); 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::M3X3(Registers &r, Vector4f &dst, Vector4f &src0, Src &src1) 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 86319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row0 = reg(r, src1, 0); 86419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row1 = reg(r, src1, 1); 86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row2 = reg(r, src1, 2); 866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.x = dot3(src0, row0); 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.y = dot3(src0, row1); 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.z = dot3(src0, row2); 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 87219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::M3X4(Registers &r, Vector4f &dst, Vector4f &src0, Src &src1) 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 87419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row0 = reg(r, src1, 0); 87519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row1 = reg(r, src1, 1); 87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row2 = reg(r, src1, 2); 87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row3 = reg(r, src1, 3); 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.x = dot3(src0, row0); 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.y = dot3(src0, row1); 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.z = dot3(src0, row2); 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.w = dot3(src0, row3); 883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::M4X3(Registers &r, Vector4f &dst, Vector4f &src0, Src &src1) 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row0 = reg(r, src1, 0); 88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row1 = reg(r, src1, 1); 88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row2 = reg(r, src1, 2); 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.x = dot4(src0, row0); 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.y = dot4(src0, row1); 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.z = dot4(src0, row2); 894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::M4X4(Registers &r, Vector4f &dst, Vector4f &src0, Src &src1) 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row0 = reg(r, src1, 0); 89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row1 = reg(r, src1, 1); 90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row2 = reg(r, src1, 2); 90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f row3 = reg(r, src1, 3); 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.x = dot4(src0, row0); 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.y = dot4(src0, row1); 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.z = dot4(src0, row2); 906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.w = dot4(src0, row3); 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::BREAK(Registers &r) 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *deadBlock = Nucleus::createBasicBlock(); 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1]; 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(breakDepth == 0) 915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex = r.enableIndex - breakDepth; 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(endBlock); 918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableBreak = r.enableBreak & ~r.enableStack[r.enableIndex]; 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bool allBreak = SignMask(r.enableBreak) == 0x0; 923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex = r.enableIndex - breakDepth; 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(allBreak, endBlock, deadBlock); 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(deadBlock); 92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex = r.enableIndex + breakDepth; 930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 93219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::BREAKC(Registers &r, Vector4f &src0, Vector4f &src1, Control control) 933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 condition; 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(control) 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 93819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break; 93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x); break; 94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break; 94119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x); break; 94219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break; 94319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x); break; 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 94819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BREAK(r, condition); 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::BREAKP(Registers &r, const Src &predicateRegister) // FIXME: Factor out parts common with BREAKC 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 condition = As<Int4>(r.p0[predicateRegister.swizzle & 0x3]); 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(predicateRegister.modifier == Shader::MODIFIER_NOT) 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition = ~condition; 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 96019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BREAK(r, condition); 96119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 96219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 96319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::BREAK(Registers &r, Int4 &condition) 96419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition &= r.enableStack[r.enableIndex]; 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *continueBlock = Nucleus::createBasicBlock(); 968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1]; 969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableBreak = r.enableBreak & ~condition; 971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bool allBreak = SignMask(r.enableBreak) == 0x0; 972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex = r.enableIndex - breakDepth; 974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(allBreak, endBlock, continueBlock); 97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(continueBlock); 97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex = r.enableIndex + breakDepth; 978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::CONTINUE(Registers &r) 98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableContinue = r.enableContinue & ~r.enableStack[r.enableIndex]; 98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::TEST() 98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman whileTest = true; 98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::CALL(Registers &r, int labelIndex, int callSiteIndex) 991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(!labelBlock[labelIndex]) 993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman labelBlock[labelIndex] = Nucleus::createBasicBlock(); 995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(callRetBlock[labelIndex].size() > 1) 99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.callStack[r.stackIndex++] = UInt(callSiteIndex); 100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 restoreLeave = r.enableLeave; 1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(labelBlock[labelIndex]); 100519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]); 100619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 100719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableLeave = restoreLeave; 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 101019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::CALLNZ(Registers &r, int labelIndex, int callSiteIndex, const Src &src) 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 101219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.type == Shader::PARAMETER_CONSTBOOL) 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 101419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CALLNZb(r, labelIndex, callSiteIndex, src); 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 101619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(src.type == Shader::PARAMETER_PREDICATE) 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 101819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CALLNZp(r, labelIndex, callSiteIndex, src); 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else ASSERT(false); 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::CALLNZb(Registers &r, int labelIndex, int callSiteIndex, const Src &boolRegister) 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bool condition = (*Pointer<Byte>(r.data + OFFSET(DrawData,vs.b[boolRegister.index])) != Byte(0)); // FIXME 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(boolRegister.modifier == Shader::MODIFIER_NOT) 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition = !condition; 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(!labelBlock[labelIndex]) 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman labelBlock[labelIndex] = Nucleus::createBasicBlock(); 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(callRetBlock[labelIndex].size() > 1) 103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.callStack[r.stackIndex++] = UInt(callSiteIndex); 104019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 restoreLeave = r.enableLeave; 1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman branch(condition, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]); 104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]); 104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 104719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableLeave = restoreLeave; 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 105019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::CALLNZp(Registers &r, int labelIndex, int callSiteIndex, const Src &predicateRegister) 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 condition = As<Int4>(r.p0[predicateRegister.swizzle & 0x3]); 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 105419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(predicateRegister.modifier == Shader::MODIFIER_NOT) 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition = ~condition; 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition &= r.enableStack[r.enableIndex]; 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(!labelBlock[labelIndex]) 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman labelBlock[labelIndex] = Nucleus::createBasicBlock(); 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 106619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(callRetBlock[labelIndex].size() > 1) 106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.callStack[r.stackIndex++] = UInt(callSiteIndex); 106919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableIndex++; 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableStack[r.enableIndex] = condition; 107319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 restoreLeave = r.enableLeave; 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 107519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Bool notAllFalse = SignMask(condition) != 0; 107619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman branch(notAllFalse, labelBlock[labelIndex], callRetBlock[labelIndex][callSiteIndex]); 107719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(callRetBlock[labelIndex][callSiteIndex]); 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableIndex--; 108019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableLeave = restoreLeave; 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::ELSE(Registers &r) 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifDepth--; 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *falseBlock = ifFalseBlock[ifDepth]; 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = Nucleus::createBasicBlock(); 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(isConditionalIf[ifDepth]) 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 condition = ~r.enableStack[r.enableIndex] & r.enableStack[r.enableIndex - 1]; 109319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Bool notAllFalse = SignMask(condition) != 0; 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(notAllFalse, falseBlock, endBlock); 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableStack[r.enableIndex] = ~r.enableStack[r.enableIndex] & r.enableStack[r.enableIndex - 1]; 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(endBlock); 1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(falseBlock); 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifFalseBlock[ifDepth] = endBlock; 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifDepth++; 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::ENDIF(Registers &r) 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifDepth--; 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = ifFalseBlock[ifDepth]; 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(endBlock); 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(endBlock); 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(isConditionalIf[ifDepth]) 1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman breakDepth--; 1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableIndex--; 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 112619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::ENDLOOP(Registers &r) 1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepDepth--; 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 113019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.aL[r.loopDepth] = r.aL[r.loopDepth] + r.increment[r.loopDepth]; // FIXME: += 113119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *testBlock = loopRepTestBlock[loopRepDepth]; 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = loopRepEndBlock[loopRepDepth]; 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(testBlock); 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(endBlock); 1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.loopDepth--; 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 114219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::ENDREP(Registers &r) 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepDepth--; 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *testBlock = loopRepTestBlock[loopRepDepth]; 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = loopRepEndBlock[loopRepDepth]; 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(testBlock); 1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(endBlock); 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.loopDepth--; 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 115619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::ENDWHILE(Registers &r) 115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 115819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman loopRepDepth--; 115919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::BasicBlock *testBlock = loopRepTestBlock[loopRepDepth]; 116119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::BasicBlock *endBlock = loopRepEndBlock[loopRepDepth]; 116219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 116319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::createBr(testBlock); 116419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(endBlock); 116519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 116619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex--; 116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); 116819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman whileTest = false; 116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 117019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::IF(Registers &r, const Src &src) 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 117319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(src.type == Shader::PARAMETER_CONSTBOOL) 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IFb(r, src); 1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 117719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(src.type == Shader::PARAMETER_PREDICATE) 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IFp(r, src); 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 118119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 118219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 118319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 condition = As<Int4>(reg(r, src).x); 118419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman IF(r, condition); 118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::IFb(Registers &r, const Src &boolRegister) 1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(ifDepth < 24 + 4); 1191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Bool condition = (*Pointer<Byte>(r.data + OFFSET(DrawData,vs.b[boolRegister.index])) != Byte(0)); // FIXME 1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 119419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(boolRegister.modifier == Shader::MODIFIER_NOT) 1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman condition = !condition; 1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *trueBlock = Nucleus::createBasicBlock(); 1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *falseBlock = Nucleus::createBasicBlock(); 1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(condition, trueBlock, falseBlock); 1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isConditionalIf[ifDepth] = false; 1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifFalseBlock[ifDepth] = falseBlock; 1206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifDepth++; 1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::IFp(Registers &r, const Src &predicateRegister) 1211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 condition = As<Int4>(r.p0[predicateRegister.swizzle & 0x3]); 1213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(predicateRegister.modifier == Shader::MODIFIER_NOT) 1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition = ~condition; 1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman IF(r, condition); 1220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::IFC(Registers &r, Vector4f &src0, Vector4f &src1, Control control) 1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Int4 condition; 1225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(control) 1227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break; 122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x); break; 123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break; 123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x); break; 123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break; 123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x); break; 1234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ASSERT(false); 1236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman IF(r, condition); 123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::IF(Registers &r, Int4 &condition) 124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 1243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman condition &= r.enableStack[r.enableIndex]; 1244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableIndex++; 1246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.enableStack[r.enableIndex] = condition; 1247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *trueBlock = Nucleus::createBasicBlock(); 1249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *falseBlock = Nucleus::createBasicBlock(); 1250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Bool notAllFalse = SignMask(condition) != 0; 1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(notAllFalse, trueBlock, falseBlock); 1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isConditionalIf[ifDepth] = true; 1256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifFalseBlock[ifDepth] = falseBlock; 1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ifDepth++; 1259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman breakDepth++; 1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::LABEL(int labelIndex) 1263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(!labelBlock[labelIndex]) 126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman labelBlock[labelIndex] = Nucleus::createBasicBlock(); 126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(labelBlock[labelIndex]); 127019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman currentLabel = labelIndex; 1271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::LOOP(Registers &r, const Src &integerRegister) 1274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.loopDepth++; 1276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.iteration[r.loopDepth] = *Pointer<Int>(r.data + OFFSET(DrawData,vs.i[integerRegister.index][0])); 1278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.aL[r.loopDepth] = *Pointer<Int>(r.data + OFFSET(DrawData,vs.i[integerRegister.index][1])); 1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.increment[r.loopDepth] = *Pointer<Int>(r.data + OFFSET(DrawData,vs.i[integerRegister.index][2])); 1280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Compiles to two instructions? 1282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman If(r.increment[r.loopDepth] == 0) 1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.increment[r.loopDepth] = 1; 1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *loopBlock = Nucleus::createBasicBlock(); 1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *testBlock = Nucleus::createBasicBlock(); 1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = Nucleus::createBasicBlock(); 1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepTestBlock[loopRepDepth] = testBlock; 1292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepEndBlock[loopRepDepth] = endBlock; 1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: jump(testBlock) 1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(testBlock); 1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(testBlock); 1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(r.iteration[r.loopDepth] > 0, loopBlock, endBlock); 1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(loopBlock); 1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.iteration[r.loopDepth] = r.iteration[r.loopDepth] - 1; // FIXME: -- 1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepDepth++; 1304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman breakDepth = 0; 1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::REP(Registers &r, const Src &integerRegister) 1308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.loopDepth++; 1310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.iteration[r.loopDepth] = *Pointer<Int>(r.data + OFFSET(DrawData,vs.i[integerRegister.index][0])); 1312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.aL[r.loopDepth] = r.aL[r.loopDepth - 1]; 1313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *loopBlock = Nucleus::createBasicBlock(); 1315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *testBlock = Nucleus::createBasicBlock(); 1316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *endBlock = Nucleus::createBasicBlock(); 1317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepTestBlock[loopRepDepth] = testBlock; 1319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepEndBlock[loopRepDepth] = endBlock; 1320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: jump(testBlock) 1322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(testBlock); 1323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(testBlock); 1324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman branch(r.iteration[r.loopDepth] > 0, loopBlock, endBlock); 1326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(loopBlock); 1327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman r.iteration[r.loopDepth] = r.iteration[r.loopDepth] - 1; // FIXME: -- 1329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman loopRepDepth++; 1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman breakDepth = 0; 1332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 133419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::WHILE(Registers &r, const Src &temporaryRegister) 133519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 133619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableIndex++; 133719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 133819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::BasicBlock *loopBlock = Nucleus::createBasicBlock(); 133919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::BasicBlock *testBlock = Nucleus::createBasicBlock(); 134019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::BasicBlock *endBlock = Nucleus::createBasicBlock(); 134119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 134219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman loopRepTestBlock[loopRepDepth] = testBlock; 134319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman loopRepEndBlock[loopRepDepth] = endBlock; 134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 restoreBreak = r.enableBreak; 134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 restoreContinue = r.enableContinue; 134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: jump(testBlock) 134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::createBr(testBlock); 135019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(testBlock); 135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableContinue = restoreContinue; 135219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 135366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Vector4f &src = reg(r, temporaryRegister); 135419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int4 condition = As<Int4>(src.x); 135519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman condition &= r.enableStack[r.enableIndex - 1]; 135619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableStack[r.enableIndex] = condition; 135719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 135819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Bool notAllFalse = SignMask(condition) != 0; 135919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman branch(notAllFalse, loopBlock, endBlock); 136019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 136119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(endBlock); 136219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableBreak = restoreBreak; 136319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 136419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::setInsertBlock(loopBlock); 136519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 136619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman loopRepDepth++; 136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman breakDepth = 0; 136819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 136919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void VertexProgram::RET(Registers &r) 1371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 137219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(currentLabel == -1) 1373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman returnBlock = Nucleus::createBasicBlock(); 1375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createBr(returnBlock); 1376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm::BasicBlock *unreachableBlock = Nucleus::createBasicBlock(); 1380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(callRetBlock[currentLabel].size() > 1) // Pop the return destination from the call stack 1382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Encapsulate 138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UInt index = r.callStack[--r.stackIndex]; 138519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 138666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman llvm::Value *value = index.loadValue(); 138719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::Value *switchInst = Nucleus::createSwitch(value, unreachableBlock, (int)callRetBlock[currentLabel].size()); 138819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for(unsigned int i = 0; i < callRetBlock[currentLabel].size(); i++) 139019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 139119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::addSwitchCase(switchInst, i, callRetBlock[currentLabel][i]); 139219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 139319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 139419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if(callRetBlock[currentLabel].size() == 1) // Jump directly to the unique return destination 139519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 139619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::createBr(callRetBlock[currentLabel][0]); 139719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 139819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else // Function isn't called 139919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 140019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Nucleus::createBr(unreachableBlock); 1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::setInsertBlock(unreachableBlock); 1404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Nucleus::createUnreachable(); 1405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 140819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::LEAVE(Registers &r) 1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 141019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman r.enableLeave = r.enableLeave & ~r.enableStack[r.enableIndex]; 141119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 141219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Return from function if all instances left 141319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Use enableLeave in other control-flow constructs 141419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 141619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::TEXLDL(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1) 141719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 141819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f tmp; 141919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sampleTexture(r, tmp, src1, src0.x, src0.y, src0.z, src0.w); 142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 142119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dst.x = tmp[(src1.swizzle >> 0) & 0x3]; 142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dst.y = tmp[(src1.swizzle >> 2) & 0x3]; 142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dst.z = tmp[(src1.swizzle >> 4) & 0x3]; 142419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dst.w = tmp[(src1.swizzle >> 6) & 0x3]; 142519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 142719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::TEX(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1) 142819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 142919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Float4 lod = Float4(0.0f); 143019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vector4f tmp; 143119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sampleTexture(r, tmp, src1, src0.x, src0.y, src0.z, lod); 1432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.x = tmp[(src1.swizzle >> 0) & 0x3]; 1434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.y = tmp[(src1.swizzle >> 2) & 0x3]; 1435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.z = tmp[(src1.swizzle >> 4) & 0x3]; 1436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dst.w = tmp[(src1.swizzle >> 6) & 0x3]; 1437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 143819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void VertexProgram::sampleTexture(Registers &r, Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q) 144019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 144119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID) 144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 144319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Pointer<Byte> texture = r.data + OFFSET(DrawData,mipmap[16]) + s.index * sizeof(Texture); 144419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sampler[s.index]->sampleTexture(texture, c, u, v, w, q, r.a0, r.a0, false, false, true); 144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Int index = As<Int>(Float(reg(r, s).x.x)); 144919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 145019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for(int i = 0; i < 16; i++) 145119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 145219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if(shader->usesSampler(i)) 145319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 145419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman If(index == i) 145519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman { 145619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Pointer<Byte> texture = r.data + OFFSET(DrawData,mipmap[16]) + i * sizeof(Texture); 145719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sampler[i]->sampleTexture(texture, c, u, v, w, q, r.a0, r.a0, false, false, true); 145819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: When the sampler states are the same, we could use one sampler and just index the texture 145919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 146019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 146119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1465