1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 26270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens// 3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License. 5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at 66270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens// 7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 86270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens// 9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software 10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and 13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License. 146270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 156270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens#include "PixelPipeline.hpp" 166270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens#include "Renderer.hpp" 176270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens#include "SamplerCore.hpp" 186270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 196270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capensnamespace sw 206270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens{ 216270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens extern bool postBlendSRGB; 226270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 23a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w) 246270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens { 25a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(state.color[0].component & 0x1) diffuse.x = convertFixed12(v[0].x); else diffuse.x = Short4(0x1000); 26a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(state.color[0].component & 0x2) diffuse.y = convertFixed12(v[0].y); else diffuse.y = Short4(0x1000); 27a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(state.color[0].component & 0x4) diffuse.z = convertFixed12(v[0].z); else diffuse.z = Short4(0x1000); 28a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(state.color[0].component & 0x8) diffuse.w = convertFixed12(v[0].w); else diffuse.w = Short4(0x1000); 29a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens 30cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(state.color[1].component & 0x1) specular.x = convertFixed12(v[1].x); else specular.x = Short4(0x0000); 31cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(state.color[1].component & 0x2) specular.y = convertFixed12(v[1].y); else specular.y = Short4(0x0000); 32cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(state.color[1].component & 0x4) specular.z = convertFixed12(v[1].z); else specular.z = Short4(0x0000); 33cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(state.color[1].component & 0x8) specular.w = convertFixed12(v[1].w); else specular.w = Short4(0x0000); 346270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 356270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 36a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::fixedFunction() 376270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens { 38a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current = diffuse; 39f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s temp(0x0000, 0x0000, 0x0000, 0x0000); 40f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 41f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(int stage = 0; stage < 8; stage++) 42f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 43f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.textureStage[stage].stageOperation == TextureStage::STAGE_DISABLE) 44f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 45f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 46f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 47f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 48f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s texture; 49f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 50f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.textureStage[stage].usesTexture) 51f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 52a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(texture, stage, stage); 53f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 54f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 55a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens blendTexture(temp, texture, stage); 56f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 57f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 58a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens specularPixel(current, specular); 596270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 606270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 61a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::applyShader(Int cMask[4]) 62f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 63f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!shader) 64f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 65a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens fixedFunction(); 66f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return; 67f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 68f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 69f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu int pad = 0; // Count number of texm3x3pad instructions 70f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s dPairing; // Destination for first pairing instruction 71f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 72f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(size_t i = 0; i < shader->getLength(); i++) 73f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 74f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Shader::Instruction *instruction = shader->getInstruction(i); 75f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Shader::Opcode opcode = instruction->opcode; 76f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 77f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // #ifndef NDEBUG // FIXME: Centralize debug output control 78f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // shader->printInstruction(i, "debug.txt"); 79f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // #endif 80f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 81f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(opcode == Shader::OPCODE_DCL || opcode == Shader::OPCODE_DEF || opcode == Shader::OPCODE_DEFI || opcode == Shader::OPCODE_DEFB) 82f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 83f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu continue; 84f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 85f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 86f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Dst &dst = instruction->dst; 87f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Src &src0 = instruction->src[0]; 88f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Src &src1 = instruction->src[1]; 89f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Src &src2 = instruction->src[2]; 90f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 91f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu unsigned short version = shader->getVersion(); 92f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu bool pairing = i + 1 < shader->getLength() && shader->getInstruction(i + 1)->coissue; // First instruction of pair 93f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu bool coissue = instruction->coissue; // Second instruction of pair 94f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 95f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s d; 96f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s s0; 97f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s s1; 98f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s s2; 99f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1009d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0); 1019d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1); 1029d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2); 103f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 104a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 x = version < 0x0104 ? v[2 + dst.index].x : v[2 + src0.index].x; 105a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 y = version < 0x0104 ? v[2 + dst.index].y : v[2 + src0.index].y; 106a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 z = version < 0x0104 ? v[2 + dst.index].z : v[2 + src0.index].z; 107a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 w = version < 0x0104 ? v[2 + dst.index].w : v[2 + src0.index].w; 108f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 109f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(opcode) 110f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 111f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_PS_1_0: break; 112f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_PS_1_1: break; 113f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_PS_1_2: break; 114f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_PS_1_3: break; 115f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_PS_1_4: break; 116f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 117f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_DEF: break; 118f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 119f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_NOP: break; 120f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_MOV: MOV(d, s0); break; 121f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_ADD: ADD(d, s0, s1); break; 122f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_SUB: SUB(d, s0, s1); break; 123f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_MAD: MAD(d, s0, s1, s2); break; 124f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_MUL: MUL(d, s0, s1); break; 125f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_DP3: DP3(d, s0, s1); break; 126f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_DP4: DP4(d, s0, s1); break; 127f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_LRP: LRP(d, s0, s1, s2); break; 128f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_TEXCOORD: 129f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(version < 0x0104) 130f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 131a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXCOORD(d, x, y, z, dst.index); 132a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens } 133f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 134f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 135f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if((src0.swizzle & 0x30) == 0x20) // .xyz 136f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 137a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXCRD(d, x, y, z, src0.index, src0.modifier == Shader::MODIFIER_DZ || src0.modifier == Shader::MODIFIER_DW); 138f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 139a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens else // .xwy 140f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 141a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXCRD(d, x, y, w, src0.index, src0.modifier == Shader::MODIFIER_DZ || src0.modifier == Shader::MODIFIER_DW); 142f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 143f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 144f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 145f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_TEXKILL: 146f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(version < 0x0104) 147f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 148a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXKILL(cMask, x, y, z); 149f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 150f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else if(version == 0x0104) 151f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 152f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.type == Shader::PARAMETER_TEXTURE) 153f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 154a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXKILL(cMask, x, y, z); 155f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 156f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 157f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 158a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXKILL(cMask, rs[dst.index]); 159f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 160f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 161f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else ASSERT(false); 162f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 163f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::OPCODE_TEX: 164f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(version < 0x0104) 165f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 166a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEX(d, x, y, z, dst.index, false); 167f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 168f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else if(version == 0x0104) 169f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 170f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(src0.type == Shader::PARAMETER_TEXTURE) 171f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 172f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if((src0.swizzle & 0x30) == 0x20) // .xyz 173f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 174a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEX(d, x, y, z, dst.index, src0.modifier == Shader::MODIFIER_DZ || src0.modifier == Shader::MODIFIER_DW); 175f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 176f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else // .xyw 177f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 178a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEX(d, x, y, w, dst.index, src0.modifier == Shader::MODIFIER_DZ || src0.modifier == Shader::MODIFIER_DW); 179f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 180f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 181f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 182f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 183a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXLD(d, s0, dst.index, src0.modifier == Shader::MODIFIER_DZ || src0.modifier == Shader::MODIFIER_DW); 184f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 185f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 186f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else ASSERT(false); 187f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 188a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXBEM: TEXBEM(d, s0, x, y, z, dst.index); break; 189a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXBEML: TEXBEML(d, s0, x, y, z, dst.index); break; 190a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXREG2AR: TEXREG2AR(d, s0, dst.index); break; 191a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXREG2GB: TEXREG2GB(d, s0, dst.index); break; 192a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X2PAD: TEXM3X2PAD(x, y, z, s0, 0, src0.modifier == Shader::MODIFIER_SIGN); break; 193a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X2TEX: TEXM3X2TEX(d, x, y, z, dst.index, s0, src0.modifier == Shader::MODIFIER_SIGN); break; 194a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X3PAD: TEXM3X3PAD(x, y, z, s0, pad++ % 2, src0.modifier == Shader::MODIFIER_SIGN); break; 195a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X3TEX: TEXM3X3TEX(d, x, y, z, dst.index, s0, src0.modifier == Shader::MODIFIER_SIGN); break; 196a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X3SPEC: TEXM3X3SPEC(d, x, y, z, dst.index, s0, s1); break; 197a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X3VSPEC: TEXM3X3VSPEC(d, x, y, z, dst.index, s0); break; 198a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_CND: CND(d, s0, s1, s2); break; 199a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXREG2RGB: TEXREG2RGB(d, s0, dst.index); break; 200a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXDP3TEX: TEXDP3TEX(d, x, y, z, dst.index, s0); break; 201a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X2DEPTH: TEXM3X2DEPTH(d, x, y, z, s0, src0.modifier == Shader::MODIFIER_SIGN); break; 202a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXDP3: TEXDP3(d, x, y, z, s0); break; 203a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXM3X3: TEXM3X3(d, x, y, z, s0, src0.modifier == Shader::MODIFIER_SIGN); break; 204a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_TEXDEPTH: TEXDEPTH(); break; 205a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_CMP0: CMP(d, s0, s1, s2); break; 206a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_BEM: BEM(d, s0, s1, dst.index); break; 207a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_PHASE: break; 208a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::OPCODE_END: break; 209f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 210f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 211f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 212f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 213f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.type != Shader::PARAMETER_VOID && opcode != Shader::OPCODE_TEXKILL) 214f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 215f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.shift > 0) 216f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 217f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x1) { d.x = AddSat(d.x, d.x); if(dst.shift > 1) d.x = AddSat(d.x, d.x); if(dst.shift > 2) d.x = AddSat(d.x, d.x); } 218f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x2) { d.y = AddSat(d.y, d.y); if(dst.shift > 1) d.y = AddSat(d.y, d.y); if(dst.shift > 2) d.y = AddSat(d.y, d.y); } 219f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x4) { d.z = AddSat(d.z, d.z); if(dst.shift > 1) d.z = AddSat(d.z, d.z); if(dst.shift > 2) d.z = AddSat(d.z, d.z); } 220f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x8) { d.w = AddSat(d.w, d.w); if(dst.shift > 1) d.w = AddSat(d.w, d.w); if(dst.shift > 2) d.w = AddSat(d.w, d.w); } 221f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 222f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else if(dst.shift < 0) 223f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 224f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x1) d.x = d.x >> -dst.shift; 225f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x2) d.y = d.y >> -dst.shift; 226f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x4) d.z = d.z >> -dst.shift; 227f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x8) d.w = d.w >> -dst.shift; 228f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 229f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 230f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.saturate) 231f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 232cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(dst.mask & 0x1) { d.x = Min(d.x, Short4(0x1000)); d.x = Max(d.x, Short4(0x0000)); } 233cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(dst.mask & 0x2) { d.y = Min(d.y, Short4(0x1000)); d.y = Max(d.y, Short4(0x0000)); } 234cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(dst.mask & 0x4) { d.z = Min(d.z, Short4(0x1000)); d.z = Max(d.z, Short4(0x0000)); } 235cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu if(dst.mask & 0x8) { d.w = Min(d.w, Short4(0x1000)); d.w = Max(d.w, Short4(0x0000)); } 236f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 237f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 238f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(pairing) 239f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 240f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x1) dPairing.x = d.x; 241f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x2) dPairing.y = d.y; 242f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x4) dPairing.z = d.z; 243f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(dst.mask & 0x8) dPairing.w = d.w; 244f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 245f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 246f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(coissue) 247f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 248f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Dst &dst = shader->getInstruction(i - 1)->dst; 249f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 250a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens writeDestination(dPairing, dst); 251f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 252f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 253f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!pairing) 254f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 255a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens writeDestination(d, dst); 256f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 257f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 258f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 2596270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 2606270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 261a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Bool PixelPipeline::alphaTest(Int cMask[4]) 2626270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens { 263cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu current.x = Min(current.x, Short4(0x0FFF)); current.x = Max(current.x, Short4(0x0000)); 264cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu current.y = Min(current.y, Short4(0x0FFF)); current.y = Max(current.y, Short4(0x0000)); 265cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu current.z = Min(current.z, Short4(0x0FFF)); current.z = Max(current.z, Short4(0x0000)); 266cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu current.w = Min(current.w, Short4(0x0FFF)); current.w = Max(current.w, Short4(0x0000)); 267f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 268f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!state.alphaTestActive()) 269f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 270f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return true; 271f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 272f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 273f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Int aMask; 274f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 275f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.transparencyAntialiasing == TRANSPARENCY_NONE) 276f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 277a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens PixelRoutine::alphaTest(aMask, current.w); 278f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 279f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(unsigned int q = 0; q < state.multiSample; q++) 280f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 281f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cMask[q] &= aMask; 282f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 283f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 284f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else if(state.transparencyAntialiasing == TRANSPARENCY_ALPHA_TO_COVERAGE) 285f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 286a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 alpha = Float4(current.w) * Float4(1.0f / 0x1000); 287f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 288a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens alphaToCoverage(cMask, alpha); 289f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 290f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else ASSERT(false); 291f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 292f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Int pass = cMask[0]; 293f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 294f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(unsigned int q = 1; q < state.multiSample; q++) 295f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 296f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu pass = pass | cMask[q]; 297f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 298f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 2996270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens return pass != 0x0; 3006270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 3016270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 302a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]) 3036270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens { 304f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!state.colorWriteActive(0)) 305f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 306f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return; 307f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 308f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 309f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4f oC; 310f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 311f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(state.targetFormat[0]) 312f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 313f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_R5G6B5: 314f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_X8R8G8B8: 315f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_X8B8G8R8: 316f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_A8R8G8B8: 317f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_A8B8G8R8: 318f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_A8: 319f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_G16R16: 320f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_A16B16G16R16: 321f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!postBlendSRGB && state.writeSRGB) 322f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 323a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens linearToSRGB12_16(current); 324f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 325f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 326f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 327a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.x <<= 4; 328a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.y <<= 4; 329a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.z <<= 4; 330a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.w <<= 4; 331f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 332f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 333f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.targetFormat[0] == FORMAT_R5G6B5) 334f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 335a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.x &= Short4(0xF800u); 336a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.y &= Short4(0xFC00u); 337a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.z &= Short4(0xF800u); 338f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 339f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 340a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens fogBlend(current, fog); 341f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 342f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(unsigned int q = 0; q < state.multiSample; q++) 343f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 344a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Pointer<Byte> buffer = cBuffer[0] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[0])); 345a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Vector4s color = current; 346f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 347f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.multiSampleMask & (1 << q)) 348f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 349a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens alphaBlend(0, buffer, color, x); 350a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens logicOperation(0, buffer, color, x); 351a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens writeColor(0, buffer, x, color, sMask[q], zMask[q], cMask[q]); 352f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 353f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 354f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 355f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_R32F: 356f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_G32R32F: 357f946d78bc45fed74fbad8343f415e2a5d0fb2187Alexis Hetu case FORMAT_X32B32G32R32F: 358f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case FORMAT_A32B32G32R32F: 359a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens convertSigned12(oC, current); 360a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens PixelRoutine::fogBlend(oC, fog); 361f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 362f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(unsigned int q = 0; q < state.multiSample; q++) 363f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 364a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Pointer<Byte> buffer = cBuffer[0] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[0])); 365f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4f color = oC; 366f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 367f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.multiSampleMask & (1 << q)) 368f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 369a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens alphaBlend(0, buffer, color, x); 370a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens writeColor(0, buffer, x, color, sMask[q], zMask[q], cMask[q]); 371f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 372f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 373f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 374f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 375f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 3766270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 3776270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 3786270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 379a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::blendTexture(Vector4s &temp, Vector4s &texture, int stage) 380f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 3815c1bdd21ac35e805af79dd426499603fc7b7f8ceAlexis Hetu Vector4s *arg1 = nullptr; 3825c1bdd21ac35e805af79dd426499603fc7b7f8ceAlexis Hetu Vector4s *arg2 = nullptr; 3835c1bdd21ac35e805af79dd426499603fc7b7f8ceAlexis Hetu Vector4s *arg3 = nullptr; 384f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s res; 385f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 386f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s constant; 387f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s tfactor; 388f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 389f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const TextureStage::State &textureStage = state.textureStage[stage]; 390f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 391f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(textureStage.firstArgument == TextureStage::SOURCE_CONSTANT || 392f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.firstArgumentAlpha == TextureStage::SOURCE_CONSTANT || 393f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.secondArgument == TextureStage::SOURCE_CONSTANT || 394f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.secondArgumentAlpha == TextureStage::SOURCE_CONSTANT || 395f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.thirdArgument == TextureStage::SOURCE_CONSTANT || 396f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.thirdArgumentAlpha == TextureStage::SOURCE_CONSTANT) 397f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 398a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens constant.x = *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].constantColor4[0])); 399a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens constant.y = *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].constantColor4[1])); 400a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens constant.z = *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].constantColor4[2])); 401a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens constant.w = *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].constantColor4[3])); 402f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 403f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 404f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(textureStage.firstArgument == TextureStage::SOURCE_TFACTOR || 405f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.firstArgumentAlpha == TextureStage::SOURCE_TFACTOR || 406f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.secondArgument == TextureStage::SOURCE_TFACTOR || 407f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.secondArgumentAlpha == TextureStage::SOURCE_TFACTOR || 408f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.thirdArgument == TextureStage::SOURCE_TFACTOR || 409f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu textureStage.thirdArgumentAlpha == TextureStage::SOURCE_TFACTOR) 410f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 411a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens tfactor.x = *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[0])); 412a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens tfactor.y = *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[1])); 413a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens tfactor.z = *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[2])); 414a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens tfactor.w = *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[3])); 415f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 416f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 417f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Premodulate 418f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(stage > 0 && textureStage.usesTexture) 419f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 420f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.textureStage[stage - 1].stageOperation == TextureStage::STAGE_PREMODULATE) 421f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 422a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.x = MulHigh(current.x, texture.x) << 4; 423a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.y = MulHigh(current.y, texture.y) << 4; 424a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.z = MulHigh(current.z, texture.z) << 4; 425f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 426f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 427f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.textureStage[stage - 1].stageOperationAlpha == TextureStage::STAGE_PREMODULATE) 428f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 429a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.w = MulHigh(current.w, texture.w) << 4; 430f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 431f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 432f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 433f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(luminance) 434f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 435a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens texture.x = MulHigh(texture.x, L) << 4; 436a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens texture.y = MulHigh(texture.y, L) << 4; 437a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens texture.z = MulHigh(texture.z, L) << 4; 438f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 439f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu luminance = false; 440f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 441f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 442f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.firstArgument) 443f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 444f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEXTURE: arg1 = &texture; break; 445f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_CONSTANT: arg1 = &constant; break; 446a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_CURRENT: arg1 = ¤t; break; 447a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_DIFFUSE: arg1 = &diffuse; break; 448a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_SPECULAR: arg1 = &specular; break; 449f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEMP: arg1 = &temp; break; 450f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TFACTOR: arg1 = &tfactor; break; 451f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 452f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 453f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 454f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 455f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.secondArgument) 456f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 457f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEXTURE: arg2 = &texture; break; 458f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_CONSTANT: arg2 = &constant; break; 459a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_CURRENT: arg2 = ¤t; break; 460a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_DIFFUSE: arg2 = &diffuse; break; 461a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_SPECULAR: arg2 = &specular; break; 462f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEMP: arg2 = &temp; break; 463f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TFACTOR: arg2 = &tfactor; break; 464f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 465f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 466f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 467f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 468f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.thirdArgument) 469f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 470f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEXTURE: arg3 = &texture; break; 471f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_CONSTANT: arg3 = &constant; break; 472a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_CURRENT: arg3 = ¤t; break; 473a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_DIFFUSE: arg3 = &diffuse; break; 474a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_SPECULAR: arg3 = &specular; break; 475f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEMP: arg3 = &temp; break; 476f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TFACTOR: arg3 = &tfactor; break; 477f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 478f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 479f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 480f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 481f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s mod1; 482f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s mod2; 483f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s mod3; 484f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 485f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.firstModifier) 486f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 487f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_COLOR: 488f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 489f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVCOLOR: 490f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.x = SubSat(Short4(0x1000), arg1->x); 491f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.y = SubSat(Short4(0x1000), arg1->y); 492f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.z = SubSat(Short4(0x1000), arg1->z); 493f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.w = SubSat(Short4(0x1000), arg1->w); 494f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 495f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg1 = &mod1; 496f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 497f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_ALPHA: 498f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.x = arg1->w; 499f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.y = arg1->w; 500f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.z = arg1->w; 501f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.w = arg1->w; 502f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 503f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg1 = &mod1; 504f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 505f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVALPHA: 506f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.x = SubSat(Short4(0x1000), arg1->w); 507f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.y = SubSat(Short4(0x1000), arg1->w); 508f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.z = SubSat(Short4(0x1000), arg1->w); 509f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.w = SubSat(Short4(0x1000), arg1->w); 510f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 511f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg1 = &mod1; 512f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 513f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 514f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 515f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 516f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 517f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.secondModifier) 518f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 519f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_COLOR: 520f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 521f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVCOLOR: 522f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.x = SubSat(Short4(0x1000), arg2->x); 523f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.y = SubSat(Short4(0x1000), arg2->y); 524f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.z = SubSat(Short4(0x1000), arg2->z); 525f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.w = SubSat(Short4(0x1000), arg2->w); 526f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 527f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg2 = &mod2; 528f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 529f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_ALPHA: 530f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.x = arg2->w; 531f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.y = arg2->w; 532f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.z = arg2->w; 533f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.w = arg2->w; 534f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 535f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg2 = &mod2; 536f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 537f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVALPHA: 538f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.x = SubSat(Short4(0x1000), arg2->w); 539f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.y = SubSat(Short4(0x1000), arg2->w); 540f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.z = SubSat(Short4(0x1000), arg2->w); 541f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.w = SubSat(Short4(0x1000), arg2->w); 542f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 543f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg2 = &mod2; 544f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 545f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 546f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 547f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 548f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 549f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.thirdModifier) 550f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 551f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_COLOR: 552f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 553f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVCOLOR: 554f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.x = SubSat(Short4(0x1000), arg3->x); 555f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.y = SubSat(Short4(0x1000), arg3->y); 556f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.z = SubSat(Short4(0x1000), arg3->z); 557f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.w = SubSat(Short4(0x1000), arg3->w); 558f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 559f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg3 = &mod3; 560f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 561f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_ALPHA: 562f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.x = arg3->w; 563f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.y = arg3->w; 564f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.z = arg3->w; 565f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.w = arg3->w; 566f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 567f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg3 = &mod3; 568f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 569f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVALPHA: 570f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.x = SubSat(Short4(0x1000), arg3->w); 571f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.y = SubSat(Short4(0x1000), arg3->w); 572f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.z = SubSat(Short4(0x1000), arg3->w); 573f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.w = SubSat(Short4(0x1000), arg3->w); 574f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 575f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg3 = &mod3; 576f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 577f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 578f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 579f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 580f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 581f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.stageOperation) 582f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 583f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DISABLE: 584f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 585f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG1: // Arg1 586f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = arg1->x; 587f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = arg1->y; 588f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = arg1->z; 589f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 590f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG2: // Arg2 591f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = arg2->x; 592f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = arg2->y; 593f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = arg2->z; 594f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 595f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG3: // Arg3 596f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = arg3->x; 597f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = arg3->y; 598f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = arg3->z; 599f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 600f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE: // Arg1 * Arg2 601f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = MulHigh(arg1->x, arg2->x) << 4; 602f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = MulHigh(arg1->y, arg2->y) << 4; 603f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = MulHigh(arg1->z, arg2->z) << 4; 604f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 605f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE2X: // Arg1 * Arg2 * 2 606f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = MulHigh(arg1->x, arg2->x) << 5; 607f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = MulHigh(arg1->y, arg2->y) << 5; 608f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = MulHigh(arg1->z, arg2->z) << 5; 609f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 610f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE4X: // Arg1 * Arg2 * 4 611f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = MulHigh(arg1->x, arg2->x) << 6; 612f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = MulHigh(arg1->y, arg2->y) << 6; 613f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = MulHigh(arg1->z, arg2->z) << 6; 614f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 615f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADD: // Arg1 + Arg2 616f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(arg1->x, arg2->x); 617f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = AddSat(arg1->y, arg2->y); 618f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = AddSat(arg1->z, arg2->z); 619f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 620f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED: // Arg1 + Arg2 - 0.5 621f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(arg1->x, arg2->x); 622f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = AddSat(arg1->y, arg2->y); 623f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = AddSat(arg1->z, arg2->z); 624f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 625cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.x = SubSat(res.x, Short4(0x0800)); 626cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.y = SubSat(res.y, Short4(0x0800)); 627cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.z = SubSat(res.z, Short4(0x0800)); 628f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 629f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED2X: // (Arg1 + Arg2 - 0.5) << 1 630f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(arg1->x, arg2->x); 631f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = AddSat(arg1->y, arg2->y); 632f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = AddSat(arg1->z, arg2->z); 633f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 634cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.x = SubSat(res.x, Short4(0x0800)); 635cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.y = SubSat(res.y, Short4(0x0800)); 636cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.z = SubSat(res.z, Short4(0x0800)); 637f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 638f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(res.x, res.x); 639f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = AddSat(res.y, res.y); 640f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = AddSat(res.z, res.z); 641f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 642f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SUBTRACT: // Arg1 - Arg2 643f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = SubSat(arg1->x, arg2->x); 644f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = SubSat(arg1->y, arg2->y); 645f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = SubSat(arg1->z, arg2->z); 646f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 647f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSMOOTH: // Arg1 + Arg2 - Arg1 * Arg2 648f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 649f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 tmp; 650f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 651f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu tmp = MulHigh(arg1->x, arg2->x) << 4; res.x = AddSat(arg1->x, arg2->x); res.x = SubSat(res.x, tmp); 652f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu tmp = MulHigh(arg1->y, arg2->y) << 4; res.y = AddSat(arg1->y, arg2->y); res.y = SubSat(res.y, tmp); 653f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu tmp = MulHigh(arg1->z, arg2->z) << 4; res.z = AddSat(arg1->z, arg2->z); res.z = SubSat(res.z, tmp); 654f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 655f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 656f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MULTIPLYADD: // Arg3 + Arg1 * Arg2 657f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = MulHigh(arg1->x, arg2->x) << 4; res.x = AddSat(res.x, arg3->x); 658f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = MulHigh(arg1->y, arg2->y) << 4; res.y = AddSat(res.y, arg3->y); 659f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = MulHigh(arg1->z, arg2->z) << 4; res.z = AddSat(res.z, arg3->z); 660f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 661f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_LERP: // Arg3 * (Arg1 - Arg2) + Arg2 662f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = SubSat(arg1->x, arg2->x); res.x = MulHigh(res.x, arg3->x) << 4; res.x = AddSat(res.x, arg2->x); 663f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = SubSat(arg1->y, arg2->y); res.y = MulHigh(res.y, arg3->y) << 4; res.y = AddSat(res.y, arg2->y); 664f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = SubSat(arg1->z, arg2->z); res.z = MulHigh(res.z, arg3->z) << 4; res.z = AddSat(res.z, arg2->z); 665f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 666f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DOT3: // 2 * (Arg1.x - 0.5) * 2 * (Arg2.x - 0.5) + 2 * (Arg1.y - 0.5) * 2 * (Arg2.y - 0.5) + 2 * (Arg1.z - 0.5) * 2 * (Arg2.z - 0.5) 667f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 668f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 tmp; 669f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 670cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.x = SubSat(arg1->x, Short4(0x0800)); tmp = SubSat(arg2->x, Short4(0x0800)); res.x = MulHigh(res.x, tmp); 671cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.y = SubSat(arg1->y, Short4(0x0800)); tmp = SubSat(arg2->y, Short4(0x0800)); res.y = MulHigh(res.y, tmp); 672cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.z = SubSat(arg1->z, Short4(0x0800)); tmp = SubSat(arg2->z, Short4(0x0800)); res.z = MulHigh(res.z, tmp); 673f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 674f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = res.x << 6; 675f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = res.y << 6; 676f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = res.z << 6; 677f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 678f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(res.x, res.y); 679f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(res.x, res.z); 680f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 681f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Clamp to [0, 1] 682cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.x = Max(res.x, Short4(0x0000)); 683f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = Min(res.x, Short4(0x1000)); 684f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 685f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = res.x; 686f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = res.x; 687f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = res.x; 688f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 689f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 690f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDCURRENTALPHA: // Alpha * (Arg1 - Arg2) + Arg2 691a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.x = SubSat(arg1->x, arg2->x); res.x = MulHigh(res.x, current.w) << 4; res.x = AddSat(res.x, arg2->x); 692a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.y = SubSat(arg1->y, arg2->y); res.y = MulHigh(res.y, current.w) << 4; res.y = AddSat(res.y, arg2->y); 693a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.z = SubSat(arg1->z, arg2->z); res.z = MulHigh(res.z, current.w) << 4; res.z = AddSat(res.z, arg2->z); 694f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 695f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDDIFFUSEALPHA: // Alpha * (Arg1 - Arg2) + Arg2 696a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.x = SubSat(arg1->x, arg2->x); res.x = MulHigh(res.x, diffuse.w) << 4; res.x = AddSat(res.x, arg2->x); 697a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.y = SubSat(arg1->y, arg2->y); res.y = MulHigh(res.y, diffuse.w) << 4; res.y = AddSat(res.y, arg2->y); 698a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.z = SubSat(arg1->z, arg2->z); res.z = MulHigh(res.z, diffuse.w) << 4; res.z = AddSat(res.z, arg2->z); 699f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 700f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDFACTORALPHA: // Alpha * (Arg1 - Arg2) + Arg2 701a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.x = SubSat(arg1->x, arg2->x); res.x = MulHigh(res.x, *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[3]))) << 4; res.x = AddSat(res.x, arg2->x); 702a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.y = SubSat(arg1->y, arg2->y); res.y = MulHigh(res.y, *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[3]))) << 4; res.y = AddSat(res.y, arg2->y); 703a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.z = SubSat(arg1->z, arg2->z); res.z = MulHigh(res.z, *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[3]))) << 4; res.z = AddSat(res.z, arg2->z); 704f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 705f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHA: // Alpha * (Arg1 - Arg2) + Arg2 706f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = SubSat(arg1->x, arg2->x); res.x = MulHigh(res.x, texture.w) << 4; res.x = AddSat(res.x, arg2->x); 707f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = SubSat(arg1->y, arg2->y); res.y = MulHigh(res.y, texture.w) << 4; res.y = AddSat(res.y, arg2->y); 708f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = SubSat(arg1->z, arg2->z); res.z = MulHigh(res.z, texture.w) << 4; res.z = AddSat(res.z, arg2->z); 709f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 710f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHAPM: // Arg1 + Arg2 * (1 - Alpha) 711f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = SubSat(Short4(0x1000), texture.w); res.x = MulHigh(res.x, arg2->x) << 4; res.x = AddSat(res.x, arg1->x); 712f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = SubSat(Short4(0x1000), texture.w); res.y = MulHigh(res.y, arg2->y) << 4; res.y = AddSat(res.y, arg1->y); 713f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = SubSat(Short4(0x1000), texture.w); res.z = MulHigh(res.z, arg2->z) << 4; res.z = AddSat(res.z, arg1->z); 714f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 715f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_PREMODULATE: 716f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = arg1->x; 717f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = arg1->y; 718f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = arg1->z; 719f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 720f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEALPHA_ADDCOLOR: // Arg1 + Arg1.w * Arg2 721f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = MulHigh(arg1->w, arg2->x) << 4; res.x = AddSat(res.x, arg1->x); 722f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = MulHigh(arg1->w, arg2->y) << 4; res.y = AddSat(res.y, arg1->y); 723f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = MulHigh(arg1->w, arg2->z) << 4; res.z = AddSat(res.z, arg1->z); 724f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 725f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATECOLOR_ADDALPHA: // Arg1 * Arg2 + Arg1.w 726f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = MulHigh(arg1->x, arg2->x) << 4; res.x = AddSat(res.x, arg1->w); 727f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = MulHigh(arg1->y, arg2->y) << 4; res.y = AddSat(res.y, arg1->w); 728f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = MulHigh(arg1->z, arg2->z) << 4; res.z = AddSat(res.z, arg1->w); 729f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 730f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR: // (1 - Arg1.w) * Arg2 + Arg1 731f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 732f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 tmp; 733f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 734f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(arg1->x, arg2->x); tmp = MulHigh(arg1->w, arg2->x) << 4; res.x = SubSat(res.x, tmp); 735f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = AddSat(arg1->y, arg2->y); tmp = MulHigh(arg1->w, arg2->y) << 4; res.y = SubSat(res.y, tmp); 736f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = AddSat(arg1->z, arg2->z); tmp = MulHigh(arg1->w, arg2->z) << 4; res.z = SubSat(res.z, tmp); 737f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 738f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 739f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA: // (1 - Arg1) * Arg2 + Arg1.w 740f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 741f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 tmp; 742f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 743f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = AddSat(arg1->w, arg2->x); tmp = MulHigh(arg1->x, arg2->x) << 4; res.x = SubSat(res.x, tmp); 744f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = AddSat(arg1->w, arg2->y); tmp = MulHigh(arg1->y, arg2->y) << 4; res.y = SubSat(res.y, tmp); 745f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = AddSat(arg1->w, arg2->z); tmp = MulHigh(arg1->z, arg2->z) << 4; res.z = SubSat(res.z, tmp); 746f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 747f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 748f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAP: 749f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 750a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du = Float4(texture.x) * Float4(1.0f / 0x0FE0); 751a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv = Float4(texture.y) * Float4(1.0f / 0x0FE0); 752f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 753f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 du2; 754f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 dv2; 755f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 756a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du2 = du; 757a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv2 = dv; 758a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][0])); 759a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][0])); 760a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du += dv2; 761a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][1])); 762a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][1])); 763a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv += du2; 764f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 765f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu perturbate = true; 766f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 767a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.x = current.x; 768a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.y = current.y; 769a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.z = current.z; 770a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.w = current.w; 771f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 772f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 773f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAPLUMINANCE: 774f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 775a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du = Float4(texture.x) * Float4(1.0f / 0x0FE0); 776a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv = Float4(texture.y) * Float4(1.0f / 0x0FE0); 777f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 778f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 du2; 779f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 dv2; 780f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 781a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du2 = du; 782a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv2 = dv; 783f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 784a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][0])); 785a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][0])); 786a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du += dv2; 787a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][1])); 788a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][1])); 789a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv += du2; 790f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 791f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu perturbate = true; 792f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 793a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = texture.z; 794a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = MulHigh(L, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].luminanceScale4))); 795a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = L << 4; 796a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = AddSat(L, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].luminanceOffset4))); 797cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu L = Max(L, Short4(0x0000)); 798a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = Min(L, Short4(0x1000)); 799f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 800f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu luminance = true; 801f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 802a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.x = current.x; 803a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.y = current.y; 804a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.z = current.z; 805a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.w = current.w; 806f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 807f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 808f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 809f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 810f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 811f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 812f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(textureStage.stageOperation != TextureStage::STAGE_DOT3) 813f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 814f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.firstArgumentAlpha) 815f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 816f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEXTURE: arg1 = &texture; break; 817f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_CONSTANT: arg1 = &constant; break; 818a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_CURRENT: arg1 = ¤t; break; 819a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_DIFFUSE: arg1 = &diffuse; break; 820a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_SPECULAR: arg1 = &specular; break; 821f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEMP: arg1 = &temp; break; 822f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TFACTOR: arg1 = &tfactor; break; 823f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 824f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 825f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 826f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 827f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.secondArgumentAlpha) 828f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 829f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEXTURE: arg2 = &texture; break; 830f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_CONSTANT: arg2 = &constant; break; 831a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_CURRENT: arg2 = ¤t; break; 832a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_DIFFUSE: arg2 = &diffuse; break; 833a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_SPECULAR: arg2 = &specular; break; 834f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEMP: arg2 = &temp; break; 835f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TFACTOR: arg2 = &tfactor; break; 836f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 837f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 838f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 839f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 840f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.thirdArgumentAlpha) 841f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 842f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEXTURE: arg3 = &texture; break; 843f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_CONSTANT: arg3 = &constant; break; 844a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_CURRENT: arg3 = ¤t; break; 845a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_DIFFUSE: arg3 = &diffuse; break; 846a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case TextureStage::SOURCE_SPECULAR: arg3 = &specular; break; 847f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TEMP: arg3 = &temp; break; 848f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::SOURCE_TFACTOR: arg3 = &tfactor; break; 849f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 850f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 851f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 852f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 853f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.firstModifierAlpha) // FIXME: Check if actually used 854f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 855f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_COLOR: 856f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 857f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVCOLOR: 858f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.w = SubSat(Short4(0x1000), arg1->w); 859f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 860f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg1 = &mod1; 861f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 862f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_ALPHA: 863f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Redudant 864f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 865f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVALPHA: 866f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod1.w = SubSat(Short4(0x1000), arg1->w); 867f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 868f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg1 = &mod1; 869f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 870f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 871f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 872f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 873f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 874f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.secondModifierAlpha) // FIXME: Check if actually used 875f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 876f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_COLOR: 877f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 878f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVCOLOR: 879f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.w = SubSat(Short4(0x1000), arg2->w); 880f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 881f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg2 = &mod2; 882f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 883f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_ALPHA: 884f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Redudant 885f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 886f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVALPHA: 887f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod2.w = SubSat(Short4(0x1000), arg2->w); 888f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 889f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg2 = &mod2; 890f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 891f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 892f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 893f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 894f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 895f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.thirdModifierAlpha) // FIXME: Check if actually used 896f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 897f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_COLOR: 898f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 899f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVCOLOR: 900f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.w = SubSat(Short4(0x1000), arg3->w); 901f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 902f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg3 = &mod3; 903f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 904f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_ALPHA: 905f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Redudant 906f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 907f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::MODIFIER_INVALPHA: 908f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod3.w = SubSat(Short4(0x1000), arg3->w); 909f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 910f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu arg3 = &mod3; 911f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 912f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 913f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 914f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 915f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 916f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.stageOperationAlpha) 917f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 918f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DISABLE: 919f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 920f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG1: // Arg1 921f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = arg1->w; 922f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 923f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG2: // Arg2 924f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = arg2->w; 925f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 926f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG3: // Arg3 927f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = arg3->w; 928f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 929f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE: // Arg1 * Arg2 930f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = MulHigh(arg1->w, arg2->w) << 4; 931f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 932f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE2X: // Arg1 * Arg2 * 2 933f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = MulHigh(arg1->w, arg2->w) << 5; 934f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 935f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE4X: // Arg1 * Arg2 * 4 936f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = MulHigh(arg1->w, arg2->w) << 6; 937f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 938f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADD: // Arg1 + Arg2 939f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = AddSat(arg1->w, arg2->w); 940f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 941f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED: // Arg1 + Arg2 - 0.5 942f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = AddSat(arg1->w, arg2->w); 943cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.w = SubSat(res.w, Short4(0x0800)); 944f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 945f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED2X: // (Arg1 + Arg2 - 0.5) << 1 946f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = AddSat(arg1->w, arg2->w); 947cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.w = SubSat(res.w, Short4(0x0800)); 948f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = AddSat(res.w, res.w); 949f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 950f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SUBTRACT: // Arg1 - Arg2 951f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = SubSat(arg1->w, arg2->w); 952f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 953f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSMOOTH: // Arg1 + Arg2 - Arg1 * Arg2 954f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 955f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 tmp; 956f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 957f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu tmp = MulHigh(arg1->w, arg2->w) << 4; res.w = AddSat(arg1->w, arg2->w); res.w = SubSat(res.w, tmp); 958f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 959f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 960f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MULTIPLYADD: // Arg3 + Arg1 * Arg2 961f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = MulHigh(arg1->w, arg2->w) << 4; res.w = AddSat(res.w, arg3->w); 962f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 963f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_LERP: // Arg3 * (Arg1 - Arg2) + Arg2 964f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = SubSat(arg1->w, arg2->w); res.w = MulHigh(res.w, arg3->w) << 4; res.w = AddSat(res.w, arg2->w); 965f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 966f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DOT3: 967f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; // Already computed in color channel 968f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDCURRENTALPHA: // Alpha * (Arg1 - Arg2) + Arg2 969a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.w = SubSat(arg1->w, arg2->w); res.w = MulHigh(res.w, current.w) << 4; res.w = AddSat(res.w, arg2->w); 970f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 971f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDDIFFUSEALPHA: // Arg1 * (Alpha) + Arg2 * (1 - Alpha) 972a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.w = SubSat(arg1->w, arg2->w); res.w = MulHigh(res.w, diffuse.w) << 4; res.w = AddSat(res.w, arg2->w); 973f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 974f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDFACTORALPHA: 975a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens res.w = SubSat(arg1->w, arg2->w); res.w = MulHigh(res.w, *Pointer<Short4>(data + OFFSET(DrawData, factor.textureFactor4[3]))) << 4; res.w = AddSat(res.w, arg2->w); 976f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 977f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHA: // Arg1 * (Alpha) + Arg2 * (1 - Alpha) 978f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = SubSat(arg1->w, arg2->w); res.w = MulHigh(res.w, texture.w) << 4; res.w = AddSat(res.w, arg2->w); 979f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 980f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHAPM: // Arg1 + Arg2 * (1 - Alpha) 981f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = SubSat(Short4(0x1000), texture.w); res.w = MulHigh(res.w, arg2->w) << 4; res.w = AddSat(res.w, arg1->w); 982f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 983f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_PREMODULATE: 984f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = arg1->w; 985f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 986f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEALPHA_ADDCOLOR: 987f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATECOLOR_ADDALPHA: 988f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR: 989f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA: 990f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAP: 991f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAPLUMINANCE: 992f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; // Invalid alpha operations 993f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 994f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 995f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 996f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 997f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 998f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Clamp result to [0, 1] 999f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1000f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.stageOperation) 1001f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1002f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DISABLE: 1003f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG1: 1004f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG2: 1005f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG3: 1006f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE: 1007f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE2X: 1008f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE4X: 1009f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADD: 1010f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MULTIPLYADD: 1011f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_LERP: 1012f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDCURRENTALPHA: 1013f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDDIFFUSEALPHA: 1014f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDFACTORALPHA: 1015f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHA: 1016f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHAPM: 1017f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DOT3: // Already clamped 1018f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_PREMODULATE: 1019f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEALPHA_ADDCOLOR: 1020f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATECOLOR_ADDALPHA: 1021f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR: 1022f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA: 1023f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAP: 1024f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAPLUMINANCE: 1025f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.textureStage[stage].cantUnderflow) 1026f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1027f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; // Can't go below zero 1028f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1029f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED: 1030f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED2X: 1031f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SUBTRACT: 1032f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSMOOTH: 1033cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.x = Max(res.x, Short4(0x0000)); 1034cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.y = Max(res.y, Short4(0x0000)); 1035cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.z = Max(res.z, Short4(0x0000)); 1036f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1037f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1038f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1039f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1040f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1041f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.stageOperationAlpha) 1042f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1043f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DISABLE: 1044f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG1: 1045f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG2: 1046f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG3: 1047f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE: 1048f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE2X: 1049f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE4X: 1050f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADD: 1051f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MULTIPLYADD: 1052f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_LERP: 1053f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDCURRENTALPHA: 1054f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDDIFFUSEALPHA: 1055f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDFACTORALPHA: 1056f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHA: 1057f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHAPM: 1058f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DOT3: // Already clamped 1059f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_PREMODULATE: 1060f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEALPHA_ADDCOLOR: 1061f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATECOLOR_ADDALPHA: 1062f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR: 1063f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA: 1064f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAP: 1065f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAPLUMINANCE: 1066f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.textureStage[stage].cantUnderflow) 1067f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1068f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; // Can't go below zero 1069f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1070f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED: 1071f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED2X: 1072f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SUBTRACT: 1073f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSMOOTH: 1074cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu res.w = Max(res.w, Short4(0x0000)); 1075f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1076f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1077f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1078f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1079f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1080f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.stageOperation) 1081f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1082f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DISABLE: 1083f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG1: 1084f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG2: 1085f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG3: 1086f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE: 1087f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SUBTRACT: 1088f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSMOOTH: 1089f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_LERP: 1090f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDCURRENTALPHA: 1091f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDDIFFUSEALPHA: 1092f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDFACTORALPHA: 1093f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHA: 1094f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DOT3: // Already clamped 1095f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_PREMODULATE: 1096f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR: 1097f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA: 1098f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAP: 1099f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAPLUMINANCE: 1100f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; // Can't go above one 1101f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE2X: 1102f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE4X: 1103f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADD: 1104f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED: 1105f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED2X: 1106f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MULTIPLYADD: 1107f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHAPM: 1108f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEALPHA_ADDCOLOR: 1109f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATECOLOR_ADDALPHA: 1110f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.x = Min(res.x, Short4(0x1000)); 1111f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.y = Min(res.y, Short4(0x1000)); 1112f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.z = Min(res.z, Short4(0x1000)); 1113f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1114f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1115f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1116f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1117f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1118f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.stageOperationAlpha) 1119f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1120f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DISABLE: 1121f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG1: 1122f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG2: 1123f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SELECTARG3: 1124f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE: 1125f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_SUBTRACT: 1126f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSMOOTH: 1127f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_LERP: 1128f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDCURRENTALPHA: 1129f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDDIFFUSEALPHA: 1130f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDFACTORALPHA: 1131f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHA: 1132f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_DOT3: // Already clamped 1133f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_PREMODULATE: 1134f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR: 1135f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA: 1136f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAP: 1137f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BUMPENVMAPLUMINANCE: 1138f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; // Can't go above one 1139f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE2X: 1140f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATE4X: 1141f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADD: 1142f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED: 1143f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_ADDSIGNED2X: 1144f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MULTIPLYADD: 1145f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_BLENDTEXTUREALPHAPM: 1146f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATEALPHA_ADDCOLOR: 1147f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::STAGE_MODULATECOLOR_ADDALPHA: 1148f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu res.w = Min(res.w, Short4(0x1000)); 1149f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1150f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1151f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1152f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1153f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1154f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(textureStage.destinationArgument) 1155f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1156f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::DESTINATION_CURRENT: 1157a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.x = res.x; 1158a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.y = res.y; 1159a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.z = res.z; 1160a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.w = res.w; 1161f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1162f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case TextureStage::DESTINATION_TEMP: 1163f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu temp.x = res.x; 1164f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu temp.y = res.y; 1165f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu temp.z = res.z; 1166f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu temp.w = res.w; 1167f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1168f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1169f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1170f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 11716270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 11726270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1173a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::fogBlend(Vector4s ¤t, Float4 &f) 1174f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1175f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!state.fogActive) 1176f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1177f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return; 1178f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1179f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1180f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.pixelFogMode != FOG_NONE) 1181f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1182a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens pixelFog(f); 1183f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1184f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1185f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu UShort4 fog = convertFixed16(f, true); 1186f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1187f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu current.x = As<Short4>(MulHigh(As<UShort4>(current.x), fog)); 1188f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu current.y = As<Short4>(MulHigh(As<UShort4>(current.y), fog)); 1189f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu current.z = As<Short4>(MulHigh(As<UShort4>(current.z), fog)); 1190f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1191f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu UShort4 invFog = UShort4(0xFFFFu) - fog; 1192f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1193a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.x += As<Short4>(MulHigh(invFog, *Pointer<UShort4>(data + OFFSET(DrawData, fog.color4[0])))); 1194a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.y += As<Short4>(MulHigh(invFog, *Pointer<UShort4>(data + OFFSET(DrawData, fog.color4[1])))); 1195a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens current.z += As<Short4>(MulHigh(invFog, *Pointer<UShort4>(data + OFFSET(DrawData, fog.color4[2])))); 11966270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 11976270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1198f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::specularPixel(Vector4s ¤t, Vector4s &specular) 1199f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1200f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!state.specularAdd) 1201f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1202f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return; 1203f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1204f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1205f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu current.x = AddSat(current.x, specular.x); 1206f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu current.y = AddSat(current.y, specular.y); 1207f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu current.z = AddSat(current.z, specular.z); 12086270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens } 12096270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1210a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::sampleTexture(Vector4s &c, int coordinates, int stage, bool project) 1211f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1212a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 x = v[2 + coordinates].x; 1213a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 y = v[2 + coordinates].y; 1214a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 z = v[2 + coordinates].z; 1215a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 w = v[2 + coordinates].w; 1216f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1217f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(perturbate) 1218f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1219a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens x += du; 1220a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens y += dv; 1221f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1222f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu perturbate = false; 1223f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1224f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1225a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(c, stage, x, y, z, w, project); 1226f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1227f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 12289d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens void PixelPipeline::sampleTexture(Vector4s &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project) 1229f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 12309d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens #if PERF_PROFILE 12319d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens Long texTime = Ticks(); 12329d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens #endif 12339d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens 1234f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4f dsx; 1235f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4f dsy; 1236f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1237a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + stage * sizeof(Texture); 1238f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1239f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(!project) 1240f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 12419d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy); 1242f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1243f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1244f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1245f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 rq = reciprocal(q); 1246f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1247f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u_q = u * rq; 1248f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v_q = v * rq; 1249f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 w_q = w * rq; 1250f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 12519d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy); 1252f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1253f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 12549d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens #if PERF_PROFILE 12559d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens cycles[PERF_TEX] += Ticks() - texTime; 12569d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens #endif 1257f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 12586270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1259f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 PixelPipeline::convertFixed12(RValue<Float4> cf) 1260f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1261f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return RoundShort4(cf * Float4(0x1000)); 1262f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1263f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1264f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::convertFixed12(Vector4s &cs, Vector4f &cf) 1265f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1266f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cs.x = convertFixed12(cf.x); 1267f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cs.y = convertFixed12(cf.y); 1268f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cs.z = convertFixed12(cf.z); 1269f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cs.w = convertFixed12(cf.w); 1270f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1271f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1272f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 PixelPipeline::convertSigned12(Short4 &cs) 1273f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1274f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return Float4(cs) * Float4(1.0f / 0x0FFE); 1275f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1276f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1277f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::convertSigned12(Vector4f &cf, Vector4s &cs) 1278f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1279f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cf.x = convertSigned12(cs.x); 1280f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cf.y = convertSigned12(cs.y); 1281f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cf.z = convertSigned12(cs.z); 1282f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cf.w = convertSigned12(cs.w); 1283f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 12846270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1285a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::writeDestination(Vector4s &d, const Dst &dst) 1286f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1287f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(dst.type) 1288f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1289f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::PARAMETER_TEMP: 1290a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x1) rs[dst.index].x = d.x; 1291a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x2) rs[dst.index].y = d.y; 1292a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x4) rs[dst.index].z = d.z; 1293a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x8) rs[dst.index].w = d.w; 1294f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1295f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::PARAMETER_INPUT: 1296a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x1) vs[dst.index].x = d.x; 1297a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x2) vs[dst.index].y = d.y; 1298a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x4) vs[dst.index].z = d.z; 1299a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x8) vs[dst.index].w = d.w; 1300f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1301f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::PARAMETER_CONST: ASSERT(false); break; 1302f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::PARAMETER_TEXTURE: 1303a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x1) ts[dst.index].x = d.x; 1304a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x2) ts[dst.index].y = d.y; 1305a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x4) ts[dst.index].z = d.z; 1306a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x8) ts[dst.index].w = d.w; 1307f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1308f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::PARAMETER_COLOROUT: 1309a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x1) vs[dst.index].x = d.x; 1310a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x2) vs[dst.index].y = d.y; 1311a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x4) vs[dst.index].z = d.z; 1312a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens if(dst.mask & 0x8) vs[dst.index].w = d.w; 1313f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1314f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1315f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1316f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1317f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 13186270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 13199d86a36eb381ffce11fc116490abf74b21f49ca5Nicolas Capens Vector4s PixelPipeline::fetchRegister(const Src &src) 1320f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1321f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s *reg; 1322f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu int i = src.index; 1323f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1324f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s c; 1325f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1326f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(src.type == Shader::PARAMETER_CONST) 1327f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1328a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens c.x = *Pointer<Short4>(data + OFFSET(DrawData, ps.cW[i][0])); 1329a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens c.y = *Pointer<Short4>(data + OFFSET(DrawData, ps.cW[i][1])); 1330a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens c.z = *Pointer<Short4>(data + OFFSET(DrawData, ps.cW[i][2])); 1331a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens c.w = *Pointer<Short4>(data + OFFSET(DrawData, ps.cW[i][3])); 1332f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1333f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1334f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(src.type) 1335f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1336a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::PARAMETER_TEMP: reg = &rs[i]; break; 1337a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::PARAMETER_INPUT: reg = &vs[i]; break; 1338f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::PARAMETER_CONST: reg = &c; break; 1339a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::PARAMETER_TEXTURE: reg = &ts[i]; break; 1340a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::PARAMETER_VOID: return rs[0]; // Dummy 1341a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case Shader::PARAMETER_FLOAT4LITERAL: return rs[0]; // Dummy 1342a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens default: ASSERT(false); return rs[0]; 1343f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1344f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1345f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Short4 &x = (*reg)[(src.swizzle >> 0) & 0x3]; 1346f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Short4 &y = (*reg)[(src.swizzle >> 2) & 0x3]; 1347f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Short4 &z = (*reg)[(src.swizzle >> 4) & 0x3]; 1348f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu const Short4 &w = (*reg)[(src.swizzle >> 6) & 0x3]; 1349f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1350f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Vector4s mod; 1351f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1352f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(src.modifier) 1353f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1354f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_NONE: 1355f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = x; 1356f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = y; 1357f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = z; 1358f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = w; 1359f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1360f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_BIAS: 1361cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.x = SubSat(x, Short4(0x0800)); 1362cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.y = SubSat(y, Short4(0x0800)); 1363cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.z = SubSat(z, Short4(0x0800)); 1364cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.w = SubSat(w, Short4(0x0800)); 1365f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1366f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_BIAS_NEGATE: 1367cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.x = SubSat(Short4(0x0800), x); 1368cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.y = SubSat(Short4(0x0800), y); 1369cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.z = SubSat(Short4(0x0800), z); 1370cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.w = SubSat(Short4(0x0800), w); 1371f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1372f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_COMPLEMENT: 1373f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = SubSat(Short4(0x1000), x); 1374f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = SubSat(Short4(0x1000), y); 1375f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = SubSat(Short4(0x1000), z); 1376f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = SubSat(Short4(0x1000), w); 1377f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1378f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_NEGATE: 1379f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = -x; 1380f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = -y; 1381f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = -z; 1382f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = -w; 1383f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1384f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_X2: 1385f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = AddSat(x, x); 1386f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = AddSat(y, y); 1387f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = AddSat(z, z); 1388f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = AddSat(w, w); 1389f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1390f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_X2_NEGATE: 1391f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = -AddSat(x, x); 1392f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = -AddSat(y, y); 1393f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = -AddSat(z, z); 1394f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = -AddSat(w, w); 1395f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1396f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_SIGN: 1397cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.x = SubSat(x, Short4(0x0800)); 1398cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.y = SubSat(y, Short4(0x0800)); 1399cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.z = SubSat(z, Short4(0x0800)); 1400cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.w = SubSat(w, Short4(0x0800)); 1401f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = AddSat(mod.x, mod.x); 1402f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = AddSat(mod.y, mod.y); 1403f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = AddSat(mod.z, mod.z); 1404f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = AddSat(mod.w, mod.w); 1405f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1406f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_SIGN_NEGATE: 1407cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.x = SubSat(Short4(0x0800), x); 1408cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.y = SubSat(Short4(0x0800), y); 1409cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.z = SubSat(Short4(0x0800), z); 1410cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.w = SubSat(Short4(0x0800), w); 1411f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = AddSat(mod.x, mod.x); 1412f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = AddSat(mod.y, mod.y); 1413f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = AddSat(mod.z, mod.z); 1414f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = AddSat(mod.w, mod.w); 1415f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1416f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_DZ: 1417f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = x; 1418f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = y; 1419f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = z; 1420f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = w; 1421f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Projection performed by texture sampler 1422f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1423f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu case Shader::MODIFIER_DW: 1424f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.x = x; 1425f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.y = y; 1426f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.z = z; 1427f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu mod.w = w; 1428f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Projection performed by texture sampler 1429f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu break; 1430f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: 1431f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu ASSERT(false); 1432f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1433f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1434f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(src.type == Shader::PARAMETER_CONST && (src.modifier == Shader::MODIFIER_X2 || src.modifier == Shader::MODIFIER_X2_NEGATE)) 1435f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1436cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.x = Min(mod.x, Short4(0x1000)); mod.x = Max(mod.x, Short4(-0x1000)); 1437cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.y = Min(mod.y, Short4(0x1000)); mod.y = Max(mod.y, Short4(-0x1000)); 1438cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.z = Min(mod.z, Short4(0x1000)); mod.z = Max(mod.z, Short4(-0x1000)); 1439cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu mod.w = Min(mod.w, Short4(0x1000)); mod.w = Max(mod.w, Short4(-0x1000)); 1440f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1441f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1442f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu return mod; 1443f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 14446270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1445f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::MOV(Vector4s &dst, Vector4s &src0) 1446f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1447f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = src0.x; 1448f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = src0.y; 1449f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = src0.z; 1450f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = src0.w; 1451f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1452f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1453f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::ADD(Vector4s &dst, Vector4s &src0, Vector4s &src1) 1454f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1455f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = AddSat(src0.x, src1.x); 1456f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = AddSat(src0.y, src1.y); 1457f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = AddSat(src0.z, src1.z); 1458f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = AddSat(src0.w, src1.w); 1459f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1460f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1461f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::SUB(Vector4s &dst, Vector4s &src0, Vector4s &src1) 1462f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1463f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = SubSat(src0.x, src1.x); 1464f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = SubSat(src0.y, src1.y); 1465f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = SubSat(src0.z, src1.z); 1466f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = SubSat(src0.w, src1.w); 1467f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1468f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1469f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::MAD(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2) 1470f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1471f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // FIXME: Long fixed-point multiply fixup 1472f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { dst.x = MulHigh(src0.x, src1.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, src2.x); } 1473f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1474f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = MulHigh(src0.y, src1.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, src2.y); 1475f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1476f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu {dst.z = MulHigh(src0.z, src1.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, src2.z); } 1477f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu {dst.w = MulHigh(src0.w, src1.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, src2.w); } 1478f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1479f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1480f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::MUL(Vector4s &dst, Vector4s &src0, Vector4s &src1) 1481f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1482f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // FIXME: Long fixed-point multiply fixup 1483f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { dst.x = MulHigh(src0.x, src1.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); } 1484f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1485f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = MulHigh(src0.y, src1.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); 1486f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1487f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu {dst.z = MulHigh(src0.z, src1.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); } 1488f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu {dst.w = MulHigh(src0.w, src1.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); } 1489f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1490f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1491f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::DP3(Vector4s &dst, Vector4s &src0, Vector4s &src1) 1492f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1493f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 t0; 1494f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 t1; 1495f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1496f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // FIXME: Long fixed-point multiply fixup 1497f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = MulHigh(src0.x, src1.x); t0 = AddSat(t0, t0); t0 = AddSat(t0, t0); t0 = AddSat(t0, t0); t0 = AddSat(t0, t0); 1498f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t1 = MulHigh(src0.y, src1.y); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); 1499f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1500f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t1 = MulHigh(src0.z, src1.z); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); 1501f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1502f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1503f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = t0; 1504f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = t0; 1505f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = t0; 1506f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = t0; 1507f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1508f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1509f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::DP4(Vector4s &dst, Vector4s &src0, Vector4s &src1) 1510f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1511f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 t0; 1512f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 t1; 1513f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1514f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // FIXME: Long fixed-point multiply fixup 1515f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = MulHigh(src0.x, src1.x); t0 = AddSat(t0, t0); t0 = AddSat(t0, t0); t0 = AddSat(t0, t0); t0 = AddSat(t0, t0); 1516f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t1 = MulHigh(src0.y, src1.y); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); 1517f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1518f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t1 = MulHigh(src0.z, src1.z); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); 1519f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1520f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t1 = MulHigh(src0.w, src1.w); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); t1 = AddSat(t1, t1); 1521f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1522f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1523f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = t0; 1524f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = t0; 1525f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = t0; 1526f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = t0; 1527f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1528f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1529f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::LRP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2) 1530f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1531f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // FIXME: Long fixed-point multiply fixup 1532f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { dst.x = SubSat(src1.x, src2.x); dst.x = MulHigh(dst.x, src0.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, src2.x); } 1533f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1534f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = SubSat(src1.y, src2.y); dst.y = MulHigh(dst.y, src0.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, src2.y); 1535f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1536f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu {dst.z = SubSat(src1.z, src2.z); dst.z = MulHigh(dst.z, src0.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, src2.z); } 1537f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu {dst.w = SubSat(src1.w, src2.w); dst.w = MulHigh(dst.w, src0.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, src2.w); } 1538f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1539f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1540f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::TEXCOORD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate) 1541f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1542f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 uw; 1543f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 vw; 1544f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 sw; 1545f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1546f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.interpolant[2 + coordinate].component & 0x01) 1547f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1548f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu uw = Max(u, Float4(0.0f)); 1549f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu uw = Min(uw, Float4(1.0f)); 1550f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = convertFixed12(uw); 1551f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1552f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1553f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1554cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu dst.x = Short4(0x0000); 1555f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1556f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1557f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.interpolant[2 + coordinate].component & 0x02) 1558f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1559f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu vw = Max(v, Float4(0.0f)); 1560f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu vw = Min(vw, Float4(1.0f)); 1561f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = convertFixed12(vw); 1562f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1563f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1564f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1565cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu dst.y = Short4(0x0000); 1566f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1567f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1568f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.interpolant[2 + coordinate].component & 0x04) 1569f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1570f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu sw = Max(s, Float4(0.0f)); 1571f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu sw = Min(sw, Float4(1.0f)); 1572f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = convertFixed12(sw); 1573f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1574f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1575f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1576cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu dst.z = Short4(0x0000); 1577f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1578f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1579f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = Short4(0x1000); 1580f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1581f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1582f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::TEXCRD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate, bool project) 1583f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1584f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 uw = u; 1585f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 vw = v; 1586f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 sw = s; 1587f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1588f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(project) 1589f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1590f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu uw *= Rcp_pp(s); 1591f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu vw *= Rcp_pp(s); 1592f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1593f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1594f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.interpolant[2 + coordinate].component & 0x01) 1595f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1596f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu uw *= Float4(0x1000); 1597f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu uw = Max(uw, Float4(-0x8000)); 1598f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu uw = Min(uw, Float4(0x7FFF)); 1599f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = RoundShort4(uw); 1600f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1601f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1602f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1603f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = Short4(0x0000); 1604f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1605f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1606f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.interpolant[2 + coordinate].component & 0x02) 1607f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1608f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu vw *= Float4(0x1000); 1609f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu vw = Max(vw, Float4(-0x8000)); 1610f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu vw = Min(vw, Float4(0x7FFF)); 1611f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = RoundShort4(vw); 1612f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1613f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1614f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1615cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu dst.y = Short4(0x0000); 1616f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1617f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1618f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(state.interpolant[2 + coordinate].component & 0x04) 1619f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1620f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu sw *= Float4(0x1000); 1621f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu sw = Max(sw, Float4(-0x8000)); 1622f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu sw = Min(sw, Float4(0x7FFF)); 1623f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = RoundShort4(sw); 1624f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1625f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu else 1626f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1627cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu dst.z = Short4(0x0000); 1628f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1629f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1630f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1631a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXDP3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src) 1632f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1633a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(u, v, s, src, 0, false); 1634f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1635a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Short4 t0 = RoundShort4(u_ * Float4(0x1000)); 1636f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1637f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = t0; 1638f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = t0; 1639f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = t0; 1640f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = t0; 1641f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1642f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1643a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXDP3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0) 1644f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1645a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(u, v, s, src0, 0, false); 1646f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1647a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v_ = Float4(0.0f); 1648a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w_ = Float4(0.0f); 1649f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1650a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u_, v_, w_, w_); 1651f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1652f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1653f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::TEXKILL(Int cMask[4], Float4 &u, Float4 &v, Float4 &s) 1654f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1655f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Int kill = SignMask(CmpNLT(u, Float4(0.0f))) & 1656f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu SignMask(CmpNLT(v, Float4(0.0f))) & 1657f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu SignMask(CmpNLT(s, Float4(0.0f))); 1658f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1659f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(unsigned int q = 0; q < state.multiSample; q++) 1660f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1661f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cMask[q] &= kill; 1662f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1663f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1664f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1665f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::TEXKILL(Int cMask[4], Vector4s &src) 1666f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1667f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 test = src.x | src.y | src.z; 1668f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Int kill = SignMask(Pack(test, test)) ^ 0x0000000F; 1669f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1670f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu for(unsigned int q = 0; q < state.multiSample; q++) 1671f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1672f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu cMask[q] &= kill; 1673f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1674f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1675f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1676a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int sampler, bool project) 1677f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1678a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, sampler, u, v, s, s, project); 1679f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1680f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1681a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXLD(Vector4s &dst, Vector4s &src, int sampler, bool project) 1682f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1683f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u = Float4(src.x) * Float4(1.0f / 0x0FFE); 1684f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v = Float4(src.y) * Float4(1.0f / 0x0FFE); 1685f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 s = Float4(src.z) * Float4(1.0f / 0x0FFE); 1686f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1687a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, sampler, u, v, s, s, project); 1688f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1689f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1690a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXBEM(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage) 1691f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1692f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 du = Float4(src.x) * Float4(1.0f / 0x0FFE); 1693f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 dv = Float4(src.y) * Float4(1.0f / 0x0FFE); 1694f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1695f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 du2 = du; 1696f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 dv2 = dv; 1697f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1698a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][0])); 1699a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][0])); 1700f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu du += dv2; 1701a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][1])); 1702a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][1])); 1703f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dv += du2; 1704f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1705f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u_ = u + du; 1706f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v_ = v + dv; 1707f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1708a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u_, v_, s, s); 1709f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1710f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1711a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXBEML(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage) 1712f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1713f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 du = Float4(src.x) * Float4(1.0f / 0x0FFE); 1714f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 dv = Float4(src.y) * Float4(1.0f / 0x0FFE); 1715f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1716f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 du2 = du; 1717f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 dv2 = dv; 1718f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1719a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][0])); 1720a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][0])); 1721f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu du += dv2; 1722a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dv *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[1][1])); 1723a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens du2 *= *Pointer<Float4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4F[0][1])); 1724f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dv += du2; 1725f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1726f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u_ = u + du; 1727f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v_ = v + dv; 1728f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1729a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u_, v_, s, s); 1730f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1731f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 L; 1732f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1733f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu L = src.z; 1734a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = MulHigh(L, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].luminanceScale4))); 1735f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu L = L << 4; 1736a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens L = AddSat(L, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].luminanceOffset4))); 1737cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu L = Max(L, Short4(0x0000)); 1738f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu L = Min(L, Short4(0x1000)); 1739f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1740f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = MulHigh(dst.x, L); dst.x = dst.x << 4; 1741f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = MulHigh(dst.y, L); dst.y = dst.y << 4; 1742f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.z = MulHigh(dst.z, L); dst.z = dst.z << 4; 1743f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1744f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1745a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXREG2AR(Vector4s &dst, Vector4s &src0, int stage) 1746f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1747f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u = Float4(src0.w) * Float4(1.0f / 0x0FFE); 1748f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v = Float4(src0.x) * Float4(1.0f / 0x0FFE); 1749f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 s = Float4(src0.z) * Float4(1.0f / 0x0FFE); 1750f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1751a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u, v, s, s); 1752f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1753f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1754a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXREG2GB(Vector4s &dst, Vector4s &src0, int stage) 1755f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1756f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u = Float4(src0.y) * Float4(1.0f / 0x0FFE); 1757f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v = Float4(src0.z) * Float4(1.0f / 0x0FFE); 1758f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 s = v; 1759f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1760a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u, v, s, s); 1761f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1762f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1763a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXREG2RGB(Vector4s &dst, Vector4s &src0, int stage) 1764f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1765f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u = Float4(src0.x) * Float4(1.0f / 0x0FFE); 1766f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v = Float4(src0.y) * Float4(1.0f / 0x0FFE); 1767f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 s = Float4(src0.z) * Float4(1.0f / 0x0FFE); 1768f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1769a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u, v, s, s); 1770f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1771f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1772a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X2DEPTH(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src, bool signedScaling) 1773f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1774a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X2PAD(u, v, s, src, 1, signedScaling); 1775f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1776f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // z / w 1777a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ *= Rcp_pp(v_); // FIXME: Set result to 1.0 when division by zero 1778f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1779a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens oDepth = u_; 1780f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1781f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1782a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X2PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling) 1783f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1784a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(u, v, s, src0, component, signedScaling); 1785f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1786f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1787a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X2TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling) 1788f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1789a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X2PAD(u, v, s, src0, 1, signedScaling); 1790f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1791a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w_ = Float4(0.0f); 1792f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1793a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u_, v_, w_, w_); 1794f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1795f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1796a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, bool signedScaling) 1797f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1798a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(u, v, s, src0, 2, signedScaling); 1799f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1800a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dst.x = RoundShort4(u_ * Float4(0x1000)); 1801a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dst.y = RoundShort4(v_ * Float4(0x1000)); 1802a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens dst.z = RoundShort4(w_ * Float4(0x1000)); 1803f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.w = Short4(0x1000); 1804f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1805f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1806a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X3PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling) 1807f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1808f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu if(component == 0 || previousScaling != signedScaling) // FIXME: Other source modifiers? 1809f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1810a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens U = Float4(src0.x); 1811a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens V = Float4(src0.y); 1812a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens W = Float4(src0.z); 1813f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1814f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu previousScaling = signedScaling; 1815f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1816f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1817a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens Float4 x = U * u + V * v + W * s; 1818f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1819f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu x *= Float4(1.0f / 0x1000); 1820f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1821f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu switch(component) 1822f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1823a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case 0: u_ = x; break; 1824a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case 1: v_ = x; break; 1825a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens case 2: w_ = x; break; 1826f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu default: ASSERT(false); 1827f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1828f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1829f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1830a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X3SPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, Vector4s &src1) 1831f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1832a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(u, v, s, src0, 2, false); 1833f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1834f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 E[3]; // Eye vector 1835f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1836f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu E[0] = Float4(src1.x) * Float4(1.0f / 0x0FFE); 1837f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu E[1] = Float4(src1.y) * Float4(1.0f / 0x0FFE); 1838f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu E[2] = Float4(src1.z) * Float4(1.0f / 0x0FFE); 1839f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1840f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Reflection 1841f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u__; 1842f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v__; 1843f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 w__; 1844f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1845f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // (u'', v'', w'') = 2 * (N . E) * N - E * (N . N) 1846a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u__ = u_ * E[0]; 1847a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v__ = v_ * E[1]; 1848a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w__ = w_ * E[2]; 1849f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu u__ += v__ + w__; 1850f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu u__ += u__; 1851f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu v__ = u__; 1852f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu w__ = u__; 1853a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u__ *= u_; 1854a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v__ *= v_; 1855a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w__ *= w_; 1856a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ *= u_; 1857a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v_ *= v_; 1858a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w_ *= w_; 1859a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ += v_ + w_; 1860a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u__ -= E[0] * u_; 1861a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v__ -= E[1] * u_; 1862a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w__ -= E[2] * u_; 1863a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens 1864a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u__, v__, w__, w__); 1865f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1866f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1867a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling) 1868f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1869a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(u, v, s, src0, 2, signedScaling); 1870f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1871a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u_, v_, w_, w_); 1872f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1873f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1874a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXM3X3VSPEC(Vector4s &dst, Float4 &x, Float4 &y, Float4 &z, int stage, Vector4s &src0) 1875f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1876a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens TEXM3X3PAD(x, y, z, src0, 2, false); 1877f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1878f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 E[3]; // Eye vector 1879f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1880a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens E[0] = v[2 + stage - 2].w; 1881a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens E[1] = v[2 + stage - 1].w; 1882a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens E[2] = v[2 + stage - 0].w; 1883f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1884f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // Reflection 1885f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 u__; 1886f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 v__; 1887f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Float4 w__; 1888f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1889f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // (u'', v'', w'') = 2 * (N . E) * N - E * (N . N) 1890a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u__ = u_ * E[0]; 1891a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v__ = v_ * E[1]; 1892a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w__ = w_ * E[2]; 1893f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu u__ += v__ + w__; 1894f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu u__ += u__; 1895f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu v__ = u__; 1896f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu w__ = u__; 1897a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u__ *= u_; 1898a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v__ *= v_; 1899a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w__ *= w_; 1900a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ *= u_; 1901a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v_ *= v_; 1902a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w_ *= w_; 1903a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ += v_ + w_; 1904a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u__ -= E[0] * u_; 1905a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v__ -= E[1] * u_; 1906a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens w__ -= E[2] * u_; 1907a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens 1908a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens sampleTexture(dst, stage, u__, v__, w__, w__); 1909f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1910f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1911a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::TEXDEPTH() 1912f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1913a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ = Float4(rs[5].x); 1914a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens v_ = Float4(rs[5].y); 1915f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1916f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // z / w 1917a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens u_ *= Rcp_pp(v_); // FIXME: Set result to 1.0 when division by zero 1918f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1919a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens oDepth = u_; 1920f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1921f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1922f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::CND(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2) 1923f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1924cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0; t0 = src0.x; t0 = CmpGT(t0, Short4(0x0800)); Short4 t1; t1 = src1.x; t1 = t1 & t0; t0 = ~t0 & src2.x; t0 = t0 | t1; dst.x = t0; }; 1925cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0; t0 = src0.y; t0 = CmpGT(t0, Short4(0x0800)); Short4 t1; t1 = src1.y; t1 = t1 & t0; t0 = ~t0 & src2.y; t0 = t0 | t1; dst.y = t0; }; 1926cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0; t0 = src0.z; t0 = CmpGT(t0, Short4(0x0800)); Short4 t1; t1 = src1.z; t1 = t1 & t0; t0 = ~t0 & src2.z; t0 = t0 | t1; dst.z = t0; }; 1927cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0; t0 = src0.w; t0 = CmpGT(t0, Short4(0x0800)); Short4 t1; t1 = src1.w; t1 = t1 & t0; t0 = ~t0 & src2.w; t0 = t0 | t1; dst.w = t0; }; 1928f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1929f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1930f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu void PixelPipeline::CMP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2) 1931f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1932cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0 = CmpGT(Short4(0x0000), src0.x); Short4 t1; t1 = src2.x; t1 &= t0; t0 = ~t0 & src1.x; t0 |= t1; dst.x = t0; }; 1933cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0 = CmpGT(Short4(0x0000), src0.y); Short4 t1; t1 = src2.y; t1 &= t0; t0 = ~t0 & src1.y; t0 |= t1; dst.y = t0; }; 1934cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0 = CmpGT(Short4(0x0000), src0.z); Short4 t1; t1 = src2.z; t1 &= t0; t0 = ~t0 & src1.z; t0 |= t1; dst.z = t0; }; 1935cb96dc100fa702162e2aee6a0c46c7615b49a7dcAlexis Hetu {Short4 t0 = CmpGT(Short4(0x0000), src0.w); Short4 t1; t1 = src2.w; t1 &= t0; t0 = ~t0 & src1.w; t0 |= t1; dst.w = t0; }; 1936f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 1937f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1938a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens void PixelPipeline::BEM(Vector4s &dst, Vector4s &src0, Vector4s &src1, int stage) 1939f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu { 1940f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 t0; 1941f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu Short4 t1; 1942f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1943f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // dst.x = src0.x + BUMPENVMAT00(stage) * src1.x + BUMPENVMAT10(stage) * src1.y 1944a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens t0 = MulHigh(src1.x, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4W[0][0]))); t0 = t0 << 4; // FIXME: Matrix components range? Overflow hazard. 1945a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens t1 = MulHigh(src1.y, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4W[1][0]))); t1 = t1 << 4; // FIXME: Matrix components range? Overflow hazard. 1946f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1947f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, src0.x); 1948f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.x = t0; 1949f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu 1950f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu // dst.y = src0.y + BUMPENVMAT01(stage) * src1.x + BUMPENVMAT11(stage) * src1.y 1951a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens t0 = MulHigh(src1.x, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4W[0][1]))); t0 = t0 << 4; // FIXME: Matrix components range? Overflow hazard. 1952a106b35e674fc2d3cbc4328554c5fc976713963dNicolas Capens t1 = MulHigh(src1.y, *Pointer<Short4>(data + OFFSET(DrawData, textureStage[stage].bumpmapMatrix4W[1][1]))); t1 = t1 << 4; // FIXME: Matrix components range? Overflow hazard. 1953f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, t1); 1954f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu t0 = AddSat(t0, src0.y); 1955f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu dst.y = t0; 1956f2a8c37e70fc0d7b5a09a1ab8db2fe9ec4017b27Alexis Hetu } 19576270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens} 19586270e94c49983d9650f05ada32cb1e8f544a05e0Nicolas Capens 1959