101e6ff90560d588418e706ce4d2a16d5a15520e5David Li/** 23225321119408735f16b72b539c9fb7d80683552David Li ** 33225321119408735f16b72b539c9fb7d80683552David Li ** Copyright 2011, The Android Open Source Project 43225321119408735f16b72b539c9fb7d80683552David Li ** 501e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** Licensed under the Apache License, Version 2.0 (the "License"); 601e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** you may not use this file except in compliance with the License. 701e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** You may obtain a copy of the License at 83225321119408735f16b72b539c9fb7d80683552David Li ** 901e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** http://www.apache.org/licenses/LICENSE-2.0 103225321119408735f16b72b539c9fb7d80683552David Li ** 1101e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** Unless required by applicable law or agreed to in writing, software 1201e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** distributed under the License is distributed on an "AS IS" BASIS, 1301e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1401e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** See the License for the specific language governing permissions and 153225321119408735f16b72b539c9fb7d80683552David Li ** limitations under the License. 163225321119408735f16b72b539c9fb7d80683552David Li */ 1701e6ff90560d588418e706ce4d2a16d5a15520e5David Li 1813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <stack> 1913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 2013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include "src/pixelflinger2/pixelflinger2.h" 2113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 22359cceccdd5673460cf06d1b80b70c80f887b0ddShih-wei Liao#include <llvm/IRBuilder.h> 2313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <llvm/Module.h> 2413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 253225321119408735f16b72b539c9fb7d80683552David Li#include "src/pixelflinger2/llvm_helper.h" 2613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 273225321119408735f16b72b539c9fb7d80683552David Liusing namespace llvm; 2813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 2913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// texture data is int pointer to surface (will cast to short for 16bpp), index is linear texel index, 3013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// format is GGLPixelFormat for surface, return type is <4 x i32> rgba 313225321119408735f16b72b539c9fb7d80683552David Listatic Value * pointSample(IRBuilder<> & builder, Value * textureData, Value * index, const GGLPixelFormat format) 3213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 3313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * texel = NULL; 3413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li switch (format) { 3513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li case GGL_PIXEL_FORMAT_RGBA_8888: 3613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateGEP(textureData, index); 3713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateLoad(textureData, "texel"); 3813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li break; 3913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li case GGL_PIXEL_FORMAT_RGBX_8888: 4013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateGEP(textureData, index); 4113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateLoad(textureData, "texel"); 4213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateOr(texel, builder.getInt32(0xff000000)); 4313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li break; 4413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li case GGL_PIXEL_FORMAT_RGB_565: { 4501e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateBitCast(textureData, PointerType::get(builder.getInt16Ty(), 0)); 4613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateGEP(textureData, index); 4713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateLoad(textureData, "texel565"); 4813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateZExt(texel, Type::getInt32Ty(builder.getContext())); 4913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 5001e6ff90560d588418e706ce4d2a16d5a15520e5David Li Value * b = builder.CreateAnd(texel, builder.getInt32(0x1f)); 5101e6ff90560d588418e706ce4d2a16d5a15520e5David Li b = builder.CreateShl(b, builder.getInt32(3)); 5201e6ff90560d588418e706ce4d2a16d5a15520e5David Li b = builder.CreateOr(b, builder.CreateLShr(b, builder.getInt32(5))); 5313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 5413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * g = builder.CreateAnd(texel, builder.getInt32(0x7e0)); 5513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li g = builder.CreateShl(g, builder.getInt32(5)); 5613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li g = builder.CreateOr(g, builder.CreateLShr(g, builder.getInt32(6))); 5713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li g = builder.CreateAnd(g, builder.getInt32(0xff00)); 5813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 5901e6ff90560d588418e706ce4d2a16d5a15520e5David Li Value * r = builder.CreateAnd(texel, builder.getInt32(0xF800)); 6001e6ff90560d588418e706ce4d2a16d5a15520e5David Li r = builder.CreateShl(r, builder.getInt32(8)); 6101e6ff90560d588418e706ce4d2a16d5a15520e5David Li r = builder.CreateOr(r, builder.CreateLShr(r, builder.getInt32(5))); 6201e6ff90560d588418e706ce4d2a16d5a15520e5David Li r = builder.CreateAnd(r, builder.getInt32(0xff0000)); 6313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 6413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateOr(r, builder.CreateOr(g, b)); 6513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li texel = builder.CreateOr(texel, builder.getInt32(0xff000000), name("texel")); 6613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li break; 6713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 6801e6ff90560d588418e706ce4d2a16d5a15520e5David Li case GGL_PIXEL_FORMAT_A_8: { 6901e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateBitCast(textureData, PointerType::get(builder.getInt8Ty(),0)); 7001e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateGEP(textureData, index); 7101e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateLoad(textureData, "texel_a8"); 7201e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateZExt(texel, builder.getInt32Ty()); 7301e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateShl(texel, builder.getInt32(24)); 7401e6ff90560d588418e706ce4d2a16d5a15520e5David Li break; 7501e6ff90560d588418e706ce4d2a16d5a15520e5David Li } 7601e6ff90560d588418e706ce4d2a16d5a15520e5David Li case GGL_PIXEL_FORMAT_L_8: { 7701e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateBitCast(textureData, PointerType::get(builder.getInt8Ty(),0)); 7801e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateGEP(textureData, index); 7901e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateLoad(textureData, "texel_l8"); 8001e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateZExt(texel, builder.getInt32Ty()); 8101e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateOr(texel, builder.CreateShl(texel, 8)); 8201e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateOr(texel, builder.CreateShl(texel, 8)); 8301e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateOr(texel, builder.getInt32(0xff000000)); 8401e6ff90560d588418e706ce4d2a16d5a15520e5David Li break; 8501e6ff90560d588418e706ce4d2a16d5a15520e5David Li } 8601e6ff90560d588418e706ce4d2a16d5a15520e5David Li case GGL_PIXEL_FORMAT_LA_88: { 8701e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateBitCast(textureData, PointerType::get(builder.getInt16Ty(),0)); 8801e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureData = builder.CreateGEP(textureData, index); 8901e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateLoad(textureData, "texel_la8"); 9001e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateZExt(texel, builder.getInt32Ty()); 9101e6ff90560d588418e706ce4d2a16d5a15520e5David Li Value * alpha = builder.CreateAnd(texel, builder.getInt32(0xff00)); 9201e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateAnd(texel, builder.getInt32(0xff)); 9301e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateOr(texel, builder.CreateShl(texel, 8)); 9401e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateOr(texel, builder.CreateShl(texel, 8)); 9501e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.CreateOr(texel, builder.CreateShl(alpha, 16)); 9601e6ff90560d588418e706ce4d2a16d5a15520e5David Li break; 9701e6ff90560d588418e706ce4d2a16d5a15520e5David Li } 9813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li case GGL_PIXEL_FORMAT_UNKNOWN: // usually means texture not set yet 99a5ca04aebd1a0df7c52e170252cf3c2f3ee3e8a2Steve Block ALOGD("pf2: pointSample: unknown format, default to 0xffff00ff \n"); 10001e6ff90560d588418e706ce4d2a16d5a15520e5David Li texel = builder.getInt32(0xffff00ff); 10113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li break; 10213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li default: 10313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li assert(0); 10413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li break; 10513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 10613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * channels = Constant::getNullValue(intVecType(builder)); 10713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 10813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// if (dstDesc && dstDesc->IsInt32Color()) { 10913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateInsertElement(channels, texel, builder.getInt32(0)); 11013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateBitCast(channels, floatVecType(builder)); 11113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// return channels; 11213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else if (!dstDesc || dstDesc->IsVectorType()) { 11301e6ff90560d588418e706ce4d2a16d5a15520e5David Li channels = builder.CreateInsertElement(channels, texel, builder.getInt32(0)); 11401e6ff90560d588418e706ce4d2a16d5a15520e5David Li channels = builder.CreateInsertElement(channels, texel, builder.getInt32(1)); 11501e6ff90560d588418e706ce4d2a16d5a15520e5David Li channels = builder.CreateInsertElement(channels, texel, builder.getInt32(2)); 11601e6ff90560d588418e706ce4d2a16d5a15520e5David Li channels = builder.CreateInsertElement(channels, texel, builder.getInt32(3)); 11713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// if (dstDesc && dstDesc->IsVectorType(Fixed8)) { 11813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateLShr(channels, constIntVec(builder, 0, 8, 16, 24)); 11913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateAnd(channels, constIntVec(builder, 0xff, 0xff, 0xff, 0xff)); 12013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateBitCast(channels, floatVecType(builder)); 12113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else if (dstDesc && dstDesc->IsVectorType(Fixed16)) { 12213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateShl(channels, constIntVec(builder, 8, 0, 0, 0)); 12313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateLShr(channels, constIntVec(builder, 0, 0, 8, 16)); 12413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateAnd(channels, constIntVec(builder, 0xff00, 0xff00, 0xff00, 0xff00)); 12513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateBitCast(channels, floatVecType(builder)); 12613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else if (!dstDesc || dstDesc->IsVectorType(Float)) { // no analysis done in vertex shader, so use default float [0,1] output 12713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li channels = builder.CreateLShr(channels, constIntVec(builder, 0, 8, 16, 24)); 12813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li channels = builder.CreateAnd(channels, constIntVec(builder, 0xff, 0xff, 0xff, 0xff)); 12913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateUIToFP(channels, floatVecType(builder)); 13013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// channels = builder.CreateFMul(channels, constFloatVec(builder, 1 / 255.0f, 1 / 255.0f, 13113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// 1 / 255.0f, 1 / 255.0f)); 13213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else 13313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// assert(0); 13413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else 13513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// assert(0); 13613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 13713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return channels; 13813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 13913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 14013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic const unsigned SHIFT = 16; 14113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 14213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// w = width - 1, h = height - 1; similar to pointSample; returns <4 x i32> rgba 1433225321119408735f16b72b539c9fb7d80683552David Listatic Value * linearSample(IRBuilder<> & builder, Value * textureData, Value * indexOffset, 14401e6ff90560d588418e706ce4d2a16d5a15520e5David Li Value * x0, Value * y0, Value * xLerp, Value * yLerp, 14501e6ff90560d588418e706ce4d2a16d5a15520e5David Li Value * w, Value * h, Value * width, Value * height, 14601e6ff90560d588418e706ce4d2a16d5a15520e5David Li const GGLPixelFormat format/*, const RegDesc * dstDesc*/) 14713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 14813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li // TODO: linear filtering needs to be fixed for texcoord outside of [0,1] 14913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * x1 = builder.CreateAdd(x0, builder.getInt32(1)); 15013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li x1 = minIntScalar(builder, x1, w); 15113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * y1 = builder.CreateAdd(y0, builder.getInt32(1)); 15213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li y1 = minIntScalar(builder, y1, h); 15313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 15413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// RegDesc regDesc; 15513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// regDesc.SetVectorType(Fixed8); 15613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 15713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * index = builder.CreateMul(y0, width); 15813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, x0); 15913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, indexOffset); 16013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * s0 = pointSample(builder, textureData, index, format/*, ®Desc*/); 16113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// s0 = builder.CreateBitCast(s0, intVecType(builder)); 16213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 16313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateMul(y0, width); 16413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, x1); 16513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, indexOffset); 16613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * s1 = pointSample(builder, textureData, index, format/*, ®Desc*/); 16713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// s1 = builder.CreateBitCast(s1, intVecType(builder)); 16813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 16913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateMul(y1, width); 17013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, x1); 17113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, indexOffset); 17213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * s2 = pointSample(builder, textureData, index, format/*, ®Desc*/); 17313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// s2 = builder.CreateBitCast(s2, intVecType(builder)); 17413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 17513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateMul(y1, width); 17613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, x0); 17713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, indexOffset); 17813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * s3 = pointSample(builder, textureData, index, format/*, ®Desc*/); 17913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// s3 = builder.CreateBitCast(s3, intVecType(builder)); 18013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 18113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * xLerpVec = intVec(builder, xLerp, xLerp, xLerp, xLerp); 18213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 18313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * h0 = builder.CreateMul(builder.CreateSub(s1, s0), xLerpVec); 18413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li // arithmetic shift right, since it's the result of subtraction, which could be negative 18513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li h0 = builder.CreateAShr(h0, constIntVec(builder, SHIFT, SHIFT, SHIFT, SHIFT)); 18613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li h0 = builder.CreateAdd(h0, s0); 18713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 18813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * h1 = builder.CreateMul(builder.CreateSub(s2, s3), xLerpVec); 18913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li h1 = builder.CreateAShr(h1, constIntVec(builder, SHIFT, SHIFT, SHIFT, SHIFT)); 19013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li h1 = builder.CreateAdd(h1, s3); 19113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 19213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * sample = builder.CreateMul(builder.CreateSub(h1, h0), 19313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li intVec(builder, yLerp, yLerp, yLerp, yLerp)); 19413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li sample = builder.CreateAShr(sample, constIntVec(builder, SHIFT, SHIFT, SHIFT, SHIFT)); 19513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li sample = builder.CreateAdd(sample, h0); 19613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 19713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return sample; 19813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// if (!dstDesc || dstDesc->IsVectorType(Float)) { 19913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// sample = builder.CreateUIToFP(sample, floatVecType(builder)); 20013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// return builder.CreateFMul(sample, constFloatVec(builder, 1 / 255.0f, 1 / 255.0f, 20113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// 1 / 255.0f, 1 / 255.0f)); 20213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else if (dstDesc && dstDesc->IsVectorType(Fixed16)) { 20313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// sample = builder.CreateShl(sample, constIntVec(builder, 8, 8, 8, 8)); 20413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// return builder.CreateBitCast(sample, floatVecType(builder)); 20513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else if (dstDesc && dstDesc->IsVectorType(Fixed8)) 20613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// return builder.CreateBitCast(sample, floatVecType(builder)); 20713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// else if (dstDesc && dstDesc->IsInt32Color()) { 20813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// sample = builder.CreateShl(sample, constIntVec(builder, 0, 8, 16, 24)); 20913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// std::vector<llvm::Value*> samples = extractVector(sample); 21013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// samples[0] = builder.CreateOr(samples[0], samples[1]); 21113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// samples[0] = builder.CreateOr(samples[0], samples[2]); 21213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// samples[0] = builder.CreateOr(samples[0], samples[3]); 21313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// sample = builder.CreateInsertElement(sample, samples[0], builder.getInt32(0)); 21413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// return builder.CreateBitCast(sample, floatVecType(builder)); 21513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else 21613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// assert(0); 21713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 21813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 21913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// dim is size - 1, since [0.0f,1.0f]->[0, size - 1] 22013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic Value * texcoordWrap(IRBuilder<> & builder, const unsigned wrap, 22113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*const ChannelType type,*/ Value * r, Value * size, Value * dim, 22213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value ** texelLerp) 22313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 224ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien Type * intType = Type::getInt32Ty(builder.getContext()); 22513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * tc = NULL; 22613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * odd = NULL; 22713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// if (Float == type) { 22813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li // convert float to fixed16 so that 16LSB are the remainder, and bit 16 is one 22913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li // mantissa is the amount between two texels, used for linear interpolation 23013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = ConstantFP::get(builder.getContext(), APFloat(float(1 << SHIFT))); 23113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateFMul(tc, r); 23213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateFPToSI(tc, intType); 23313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else if (Fixed16 == type) { 23413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// assert(16 == SHIFT); 23513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// tc = builder.CreateBitCast(r, Type::getInt32Ty(builder.getContext())); 23613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } else 23713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// assert(0); 23813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 23913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li odd = builder.CreateAnd(tc, builder.getInt32(1 << SHIFT), name("tc_odd")); 24013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 24113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (0 == wrap || 2 == wrap) // just the mantissa for wrap and mirrored 24213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateAnd(tc, builder.getInt32((1 << SHIFT) - 1)); 24313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 24413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateMul(tc, dim); 24513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 24613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li *texelLerp = builder.CreateAnd(tc, builder.getInt32((1 << SHIFT) - 1)); 24713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 24813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateLShr(tc, builder.getInt32(SHIFT)); 24913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 25013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (0 == wrap) // GL_REPEAT 25113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { } else if (1 == wrap) { // GL_CLAMP_TO_EDGE 25213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = maxIntScalar(builder, tc, builder.getInt32(0)); 25313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = minIntScalar(builder, tc, dim); 25413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } else if (2 == wrap) { // GL_MIRRORER_REPEAT 25513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * tcPtr = builder.CreateAlloca(intType); 25613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(tc, tcPtr); 25713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li odd = builder.CreateICmpNE(odd, builder.getInt32(0)); 25813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 25913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li CondBranch condBranch(builder); 26013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.ifCond(odd); 26113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 26213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateSub(dim, tc, name("tc_mirrored")); 26313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(tc, tcPtr); 26413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 26513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.endif(); 26613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 26713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li tc = builder.CreateLoad(tcPtr); 26813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } else 26913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li assert(0); 27013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 27113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return tc; 27213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 27313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 27413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiValue * tex2D(IRBuilder<> & builder, Value * in1, const unsigned sampler, 27513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*const RegDesc * in1Desc, const RegDesc * dstDesc,*/ 2762ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li const GGLState * gglCtx) 27713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 278ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien Type * intType = builder.getInt32Ty(); 279ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien PointerType * intPointerType = PointerType::get(intType, 0); 28013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 28113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li llvm::Module * module = builder.GetInsertBlock()->getParent()->getParent(); 28213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li std::vector<Value * > texcoords = extractVector(builder, in1); 28313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 28413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureDimensions = module->getGlobalVariable(_PF2_TEXTURE_DIMENSIONS_NAME_); 28513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (!textureDimensions) 28613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureDimensions = new GlobalVariable(*module, intType, true, 28713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li GlobalValue::ExternalLinkage, 28813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li NULL, _PF2_TEXTURE_DIMENSIONS_NAME_); 28913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureWidth = builder.CreateConstInBoundsGEP1_32(textureDimensions, 29013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li sampler * 2); 29113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureWidth = builder.CreateLoad(textureWidth, name("textureWidth")); 29213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureHeight = builder.CreateConstInBoundsGEP1_32(textureDimensions, 29313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li sampler * 2 + 1); 29413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureHeight = builder.CreateLoad(textureHeight, name("textureHeight")); 29513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureW = builder.CreateSub(textureWidth, builder.getInt32(1)); 29613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureH = builder.CreateSub(textureHeight, builder.getInt32(1)); 29713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// ChannelType sType = Float, tType = Float; 29813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// if (in1Desc) { 29913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// sType = in1Desc->channels[0]; 30013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// tType = in1Desc->channels[1]; 30113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// } 30213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 30313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * xLerp = NULL, * yLerp = NULL; 30413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * x = texcoordWrap(builder, gglCtx->textureState.textures[sampler].wrapS, 30513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*sType, */texcoords[0], textureWidth, textureW, &xLerp); 30613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * y = texcoordWrap(builder, gglCtx->textureState.textures[sampler].wrapT, 30713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*tType, */texcoords[1], textureHeight, textureH, &yLerp); 30813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 30913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * index = builder.CreateMul(y, textureWidth); 31013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li index = builder.CreateAdd(index, x); 31113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 31213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureData = module->getGlobalVariable(_PF2_TEXTURE_DATA_NAME_); 31313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (!textureData) 31413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = new GlobalVariable(*module, intPointerType, 31513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li true, GlobalValue::ExternalLinkage, 31613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li NULL, _PF2_TEXTURE_DATA_NAME_); 31713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 31813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateConstInBoundsGEP1_32(textureData, sampler); 31913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateLoad(textureData); 32013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 32113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (0 == gglCtx->textureState.textures[sampler].minFilter && 32213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 0 == gglCtx->textureState.textures[sampler].magFilter) { // GL_NEAREST 32313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * ret = pointSample(builder, textureData, index, 32413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li gglCtx->textureState.textures[sampler].format/*, dstDesc*/); 32513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return intColorVecToFloatColorVec(builder, ret); 32613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } else if (1 == gglCtx->textureState.textures[sampler].minFilter && 32713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 1 == gglCtx->textureState.textures[sampler].magFilter) { // GL_LINEAR 32813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * ret = linearSample(builder, textureData, builder.getInt32(0), x, y, xLerp, yLerp, 32913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureW, textureH, textureWidth, textureHeight, 33013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li gglCtx->textureState.textures[sampler].format/*, dstDesc*/); 33113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return intColorVecToFloatColorVec(builder, ret); 33213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } else 33313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li assert(!"unsupported texture filter"); 33413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return NULL; 33513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 33613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 33713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// only positive float; used in cube map since major axis is positive 33813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic Value * FCmpGT(IRBuilder<> & builder, Value * lhs, Value * rhs) 33913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 340ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien Type * const intType = Type::getInt32Ty(builder.getContext()); 34113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li lhs = builder.CreateBitCast(lhs, intType); 34213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li rhs = builder.CreateBitCast(rhs, intType); 34313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return builder.CreateICmpUGT(lhs, rhs); 34413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 34513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 34613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic Value * FPositive(IRBuilder<> & builder, Value * val) 34713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 34813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li // float cmp faster here 34913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return builder.CreateFCmpOGE(val, Constant::getNullValue(builder.getFloatTy())); 35013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //val = builder.CreateBitCast(val, Type::getInt32Ty(builder.getContext())); 35113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //return builder.CreateICmpSGE(val, storage->constantInt(0)); 35213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //val = builder.CreateAnd(val, storage->constantInt(0x80000000)); 35313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //return builder.CreateICmpNE(val, storage->constantInt(0)); 35413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 35513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 35613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic Value * Fabs(IRBuilder<> & builder, Value * val) 35713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 35813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li val = builder.CreateBitCast(val, builder.getInt32Ty()); 35913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li val = builder.CreateAnd(val, builder.getInt32(~0x80000000)); 36013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return builder.CreateBitCast(val, builder.getFloatTy()); 36113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //return builder.CreateICmpSGE(val, storage->constantInt(0)); 36213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 36313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 36413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiValue * texCube(IRBuilder<> & builder, Value * in1, const unsigned sampler, 36513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*const RegDesc * in1Desc, const RegDesc * dstDesc,*/ 3662ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li const GGLState * gglCtx) 36713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ 36813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// if (in1Desc) // the major axis determination code is only float for now 36913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// assert(in1Desc->IsVectorType(Float)); 37013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 371ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien Type * const intType = builder.getInt32Ty(); 372ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien PointerType * const intPointerType = PointerType::get(intType, 0); 373ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien Type * const floatType = builder.getFloatTy(); 37413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 37513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Constant * const float1 = constFloat(builder, 1.0f); 37613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Constant * const float0_5 = constFloat(builder, 0.5f); 37713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 37813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Module * module = builder.GetInsertBlock()->getParent()->getParent(); 37913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li std::vector<Value * > texcoords = extractVector(builder, in1); 38013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 38136ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li Value * textureDimensions = module->getGlobalVariable(_PF2_TEXTURE_DIMENSIONS_NAME_); 38213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (!textureDimensions) 38313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureDimensions = new GlobalVariable(*module, intType, true, 38413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li GlobalValue::ExternalLinkage, 38536ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li NULL, _PF2_TEXTURE_DIMENSIONS_NAME_); 38613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureWidth = builder.CreateConstInBoundsGEP1_32(textureDimensions, 38713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li sampler * 2); 38813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureWidth = builder.CreateLoad(textureWidth, name("textureWidth")); 38913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureHeight = builder.CreateConstInBoundsGEP1_32(textureDimensions, 39013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li sampler * 2 + 1); 39113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureHeight = builder.CreateLoad(textureHeight, name("textureHeight")); 39213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureW = builder.CreateSub(textureWidth, builder.getInt32(1)); 39313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * textureH = builder.CreateSub(textureHeight, builder.getInt32(1)); 39413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 39513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * mx = Fabs(builder, texcoords[0]), * my = Fabs(builder, texcoords[1]); 39613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * mz = Fabs(builder, texcoords[2]); 39713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * sPtr = builder.CreateAlloca(floatType); 39813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * tPtr = builder.CreateAlloca(floatType); 39913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * maPtr = builder.CreateAlloca(floatType); 40013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * facePtr = builder.CreateAlloca(intType); 40113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 40213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * mxGmyCmp = FCmpGT(builder, mx, my); 40313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * mxGmzCmp = FCmpGT(builder, mx, mz); 40413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 40513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li CondBranch condBranch(builder); 40613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.ifCond(builder.CreateAnd(mxGmyCmp, mxGmzCmp)); // if (mx > my && mx > mz) 40713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 40813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 40913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.ifCond(FPositive(builder, texcoords[0])); 41013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 41113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 41213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[2]), sPtr); 41313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[1]), tPtr); 41413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.getInt32(0), facePtr); 41513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 41613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.elseop(); 41713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 41813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 41913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore((texcoords[2]), sPtr); 42013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[1]), tPtr); 42113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.getInt32(1), facePtr); 42213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 42313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.endif(); // end if (x >= 0) 42413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 42513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 42613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(mx, maPtr); 42713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 42813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.elseop(); // !(mx > my && mx > mz) 42913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 43013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 43113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * myGmxCmp = FCmpGT(builder, my, mx); 43213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * myGmzCmp = FCmpGT(builder, my, mz); 43313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.ifCond(builder.CreateAnd(myGmxCmp, myGmzCmp)); // my > mx && my > mz 43413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 43513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 43613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.ifCond(FPositive(builder, texcoords[1])); 43713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 43813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 43913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore((texcoords[0]), sPtr); 44013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore((texcoords[2]), tPtr); 44113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.getInt32(2), facePtr); 44213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 44313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.elseop(); 44413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 44513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 44613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(texcoords[0], sPtr); 44713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[2]), tPtr); 44813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.getInt32(3), facePtr); 44913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 45013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.endif(); 45113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 45213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 45313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(my, maPtr); 45413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 45513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.elseop(); // !(my > mx && my > mz) 45613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 45713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 45813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //ifCond(builder.CreateFCmpOGE(texcoords[2], float0, name("zPositive"))); 45913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.ifCond(FPositive(builder, texcoords[2])); 46013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 46113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 46213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore((texcoords[0]), sPtr); 46313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[1]), tPtr); 46413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.getInt32(4), facePtr); 46513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 46613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.elseop(); 46713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 46813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li { 46913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[0]), sPtr); 47013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.CreateFNeg(texcoords[1]), tPtr); 47113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(builder.getInt32(5), facePtr); 47213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 47313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.endif(); // end if (x >= 0) 47413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 47513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 47613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li builder.CreateStore(mz, maPtr); 47713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 47813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.endif(); 47913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 48013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } 48113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li condBranch.endif(); 48213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// m_storage->setCurrentBlock(currentBlock(), false); 48313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 48413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 48513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * s = builder.CreateLoad(sPtr); 48613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * t = builder.CreateLoad(tPtr); 48713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * ma = builder.CreateLoad(maPtr); 48813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * face = builder.CreateLoad(facePtr); 48913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 49013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li s = builder.CreateFDiv(s, ma); 49113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li s = builder.CreateFAdd(s, float1); 49213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li s = builder.CreateFMul(s, float0_5); 49313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 49413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li t = builder.CreateFDiv(t, ma); 49513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li t = builder.CreateFAdd(t, float1); 49613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li t = builder.CreateFMul(t, float0_5); 49713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 49813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li// ChannelType sType = Float, tType = Float; 49913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * xLerp = NULL, * yLerp = NULL; 50013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * x = texcoordWrap(builder, gglCtx->textureState.textures[sampler].wrapS, 50113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*sType, */s, textureWidth, textureW, &xLerp); 50213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * y = texcoordWrap(builder, gglCtx->textureState.textures[sampler].wrapT, 50313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li /*tType, */t, textureHeight, textureH, &yLerp); 50413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * indexOffset = builder.CreateMul(builder.CreateMul(textureHeight, textureWidth), face); 50513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li Value * index = builder.CreateAdd(builder.CreateMul(y, textureWidth), x); 50613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 50736ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li Value * textureData = module->getGlobalVariable(_PF2_TEXTURE_DATA_NAME_); 50813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (!textureData) 50913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = new GlobalVariable(*module, intPointerType, 51013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li true, GlobalValue::ExternalLinkage, 51136ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li NULL, _PF2_TEXTURE_DATA_NAME_); 51213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 51313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateConstInBoundsGEP1_32(textureData, sampler); 51413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = builder.CreateLoad(textureData); 51513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 51613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li if (0 == gglCtx->textureState.textures[sampler].minFilter && 51713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 0 == gglCtx->textureState.textures[sampler].magFilter) { // GL_NEAREST 51813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = pointSample(builder, textureData, builder.CreateAdd(indexOffset, index), 51901e6ff90560d588418e706ce4d2a16d5a15520e5David Li gglCtx->textureState.textures[sampler].format/*, dstDesc*/); 52013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return intColorVecToFloatColorVec(builder, textureData); 52101e6ff90560d588418e706ce4d2a16d5a15520e5David Li 52213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } else if (1 == gglCtx->textureState.textures[sampler].minFilter && 52313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 1 == gglCtx->textureState.textures[sampler].magFilter) { // GL_LINEAR 52413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li textureData = linearSample(builder, textureData, indexOffset, x, y, xLerp, yLerp, 52501e6ff90560d588418e706ce4d2a16d5a15520e5David Li textureW, textureH, textureWidth, textureHeight, 52601e6ff90560d588418e706ce4d2a16d5a15520e5David Li gglCtx->textureState.textures[sampler].format/*, dstDesc*/); 52713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return intColorVecToFloatColorVec(builder, textureData); 52813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li } else 52913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li assert(!"unsupported texture filter"); 53013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li return NULL; 53113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} 532