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