113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li/**
213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** Copyright 2010, The Android Open Source Project
413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** Licensed under the Apache License, Version 2.0 (the "License");
613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** you may not use this file except in compliance with the License.
713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** You may obtain a copy of the License at
813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **     http://www.apache.org/licenses/LICENSE-2.0
1013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
1113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** Unless required by applicable law or agreed to in writing, software
1213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** distributed under the License is distributed on an "AS IS" BASIS,
1313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** See the License for the specific language governing permissions and
1513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** limitations under the License.
1613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li */
1713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
1813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include "texture.h"
1913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
2013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <assert.h>
2113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <string.h>
2213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <math.h>
2313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
2413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include "pixelflinger2.h"
2513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
2613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#if USE_LLVM_EXECUTIONENGINE
2713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <llvm/Module.h>
2813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <llvm/ExecutionEngine/JIT.h>
2913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <llvm/DerivedTypes.h>
3013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#endif
3113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
3213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#if !USE_LLVM_TEXTURE_SAMPLER
3313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
3413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Liconst struct GGLContext * textureGGLContext;
3513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
3613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Liunion Pixel { unsigned char channels[4]; unsigned int val; };
3713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
3813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic inline void PixelRGBAToVector4 (const Pixel *pixel, Vector4 * color)  __attribute__((always_inline));
3913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic inline void PixelRGBAToVector4 (const Pixel *pixel, Vector4 * color)
4013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
4113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#if defined(__ARM_HAVE_NEON) && USE_NEON
4213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    int32x4_t c;
4313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    c = vsetq_lane_s32(pixel->channels[0], c, 0);
4413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    c = vsetq_lane_s32(pixel->channels[1], c, 1);
4513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    c = vsetq_lane_s32(pixel->channels[2], c, 2);
4613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    c = vsetq_lane_s32(pixel->channels[3], c, 3);
4713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    color->f4 = vcvtq_f32_s32(c);
4813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    color->f4 = vmulq_n_f32(color->f4, 1 / 255.0f);
4913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#else
5013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	color->r = (float)pixel->channels[0] / 255;
5113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	color->g = (float)pixel->channels[1] / 255;
5213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	color->b = (float)pixel->channels[2] / 255;
5313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	color->a = (float)pixel->channels[3] / 255;
5413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#endif
5513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
5613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
5713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic inline void RGBAToVector4(const unsigned int rgba, Vector4 * color)
5813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
5913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	PixelRGBAToVector4((const Pixel *)&rgba, color);
6013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
6113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
6213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic inline void Lerp(Vec4<int> * a, Vec4<int> * b, int x, Vec4<int> * d)
6313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
6413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    for (unsigned i = 0; i < 4; i++)
6513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
6613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        int r = b->i[i] - a->i[i], s = a->i[i];
6713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        d->i[i] = (r * x >> 16) + s;
6813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
6913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
7013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
7113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic inline void ToIntVec(Vec4<int> * a)
7213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
7313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    a->u[3] = a->u[0] >> 24;
7413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    a->u[2] = (a->u[0] >> 16) & 0xff;
7513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    a->u[1] = (a->u[0] >> 8) & 0xff;
7613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    a->u[0] &= 0xff;
7713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
7813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
7913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Litemplate<GGLPixelFormat format>
8013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void PointSample(unsigned sample[4], const unsigned * data, const unsigned index)
8113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
8213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (GGL_PIXEL_FORMAT_RGBA_8888 == format)
8313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        *sample = *(data + index);
8413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (GGL_PIXEL_FORMAT_RGBX_8888 == format)
8513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
8613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        *sample = *(data + index);
8713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        *sample |= 0xff000000;
8813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
8913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (GGL_PIXEL_FORMAT_RGB_565 == format)
9013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
9113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] = *((const unsigned short *)data + index);
9213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[1] = (sample[0] & 0x7e0) << 5;
9313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[2] = (sample[0] & 0xf800) << 8;
9413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] = (sample[0] & 0x1f) << 3;
9513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
9613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] |= sample[0] >> 5;
9713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[1] = (sample[1] | (sample[1] >> 6)) & 0xff00;
9813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[2] = (sample[2] | (sample[2] >> 5)) & 0xff0000;
9913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
10013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] |= sample[1];
10113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] |= sample[2];
10213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] |= 0xff000000;
10313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
10413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (GGL_PIXEL_FORMAT_UNKNOWN == format)
10513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] = 0xff00ffff;
10613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else
10713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        assert(0);
10813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
10913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
11013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic unsigned texcoordWrap(const unsigned wrap, float r, const unsigned size,
11113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li                                    unsigned * lerp)
11213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
11313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned shift = 16;
11413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    unsigned odd = 0;
11513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    int tc;
11613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
11713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    tc = r * (1 << shift);
11813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
11913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    odd = tc & (1 << shift);
12013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (0 == wrap || 2 == wrap) // REPEAT or MIRRORED
12113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        tc &= (1 << shift) - 1; // only take mantissa
12213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    tc *= size - 1;
12313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    // TODO DXL linear filtering needs to be fixed for texcoord outside of [0,1]
12413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    *lerp = tc & ((1 << shift) - 1);
12513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    tc >>= shift;
12613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
12713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (0 == wrap) // GL_REPEAT
12813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    { }
12913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (1 == wrap) // GL_CLAMP_TO_EDGE
13013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        tc = MIN2(size - 1, MAX2(0, tc));
13113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (2 == wrap)
13213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        tc = odd ? size - 1 - tc : tc;
13313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else
13413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        assert(0);
13513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    return tc;
13613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
13713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
13813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Litemplate<GGLPixelFormat format, ChannelType output, unsigned minMag, unsigned wrapS, unsigned wrapT>
13913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void tex2d(unsigned sample[4], const float tex_coord[4], const unsigned sampler)
14013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
14113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li   const unsigned * data = (const unsigned *)textureGGLContext->textureState.textureData[sampler];
14213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li   const unsigned width = textureGGLContext->textureState.textureDimensions[sampler * 2];
14313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	const unsigned height = textureGGLContext->textureState.textureDimensions[sampler * 2 + 1];
14413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    unsigned xLerp = 0, yLerp = 0;
14513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned x0 = texcoordWrap(wrapS, tex_coord[0], width, &xLerp);
14613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned y0 = texcoordWrap(wrapT, tex_coord[1], height, &yLerp);
14713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
14813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (0 == minMag)
14913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
15013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>(sample, data, y0 * width + x0);
15113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[1] = (sample[0] & 0xff00) >> 8;
15213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[2] = (sample[0] & 0xff0000) >> 16;
15313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[3] = (sample[0] & 0xff000000) >> 24;
15413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] &= 0xff;
15513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
15613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (1 == minMag)
15713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
15813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        const unsigned x1 = MIN2(width - 1, x0 + 1), y1 = MIN2(height - 1, y0 + 1);
15913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Vec4<int> samples[4] = {0};
16013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 0), data, y0 * width + x0);
16113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 0);
16213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 1), data, y0 * width + x1);
16313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 1);
16413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 2), data, y1 * width + x1);
16513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 2);
16613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 3), data, y1 * width + x0);
16713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 3);
16813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
16913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Lerp(samples + 0, samples + 1, xLerp, samples + 0);
17013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Lerp(samples + 3, samples + 2, xLerp, samples + 3);
17113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Lerp(samples + 0, samples + 3, yLerp, (Vec4<int> *)sample);
17213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
17313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else
17413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        assert(0);
17513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
17613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (Fixed0 == output) // i32 non vector
17713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] = (sample[3] << 24) | (sample[2] << 16) | (sample[1] << 8) | sample[0];
17813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (Fixed8 == output) // 4 x i32
17913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ; // do nothing
18013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (Fixed16 == output) // 4 x i32
18113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
18213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] <<= 8; sample[1] <<= 8; sample[2] <<= 8; sample[3] <<= 8;
18313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
18413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (Float == output) // 4 x float
18513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
18613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        float * fsample = (float *)sample;
18713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        fsample[0] = sample[0] / 255.0f; fsample[1] = sample[1] / 255.0f;
18813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        fsample[2] = sample[2] / 255.0f; fsample[3] = sample[3] / 255.0f;
18913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
19013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
19113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
19213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Litemplate<GGLPixelFormat format, ChannelType output, unsigned minMag, unsigned wrapS, unsigned wrapT>
19313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Livoid texcube(unsigned sample[4], const float tex_coord[4], const unsigned sampler)
19413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
19513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    float mx = fabs(tex_coord[0]), my = fabs(tex_coord[1]), mz = fabs(tex_coord[2]);
19613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    float s = 0, t = 0, ma = 0;
19713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    unsigned face = 0;
19813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (mx > my && mx > mz)
19913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
20013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        if (tex_coord[0] >= 0)
20113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        {
20213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            s = -tex_coord[2];
20313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            t = -tex_coord[1];
20413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            face = 0;
20513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        }
20613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        else
20713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        {
20813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            s = tex_coord[2];
20913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            t = -tex_coord[1];
21013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            face = 1;
21113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        }
21213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ma = mx;
21313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
21413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (my > mx && my > mz)
21513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
21613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        if (tex_coord[1] >= 0)
21713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        {
21813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            s = tex_coord[0];
21913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            t = tex_coord[2];
22013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            face = 2;
22113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        }
22213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        else
22313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        {
22413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            s = tex_coord[0];
22513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            t = -tex_coord[2];
22613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            face = 3;
22713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        }
22813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ma = my;
22913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
23013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else
23113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
23213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        if (tex_coord[2] >= 0)
23313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        {
23413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            s = tex_coord[0];
23513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            t = -tex_coord[1];
23613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            face = 4;
23713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        }
23813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        else
23913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        {
24013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            s = -tex_coord[0];
24113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            t = -tex_coord[2];
24213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            face = 5;
24313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        }
24413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ma = mz;
24513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
24613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
24713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    s = (s / ma + 1) * 0.5f;
24813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    t = (t / ma + 1) * 0.5f;
24913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
25013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned * data = (const unsigned *)textureGGLContext->textureState.textureData[sampler];
25113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned width = textureGGLContext->textureState.textureDimensions[sampler * 2];
25213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	const unsigned height = textureGGLContext->textureState.textureDimensions[sampler * 2 + 1];
25313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    unsigned xLerp = 0, yLerp = 0;
25413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned x0 = texcoordWrap(wrapS, s, width, &xLerp);
25513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const unsigned y0 = texcoordWrap(wrapT, t, height, &yLerp);
25613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
25713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (0 == minMag)
25813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
25913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>(sample, data, y0 * width + x0);
26013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[1] = (sample[0] & 0xff00) >> 8;
26113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[2] = (sample[0] & 0xff0000) >> 16;
26213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[3] = (sample[0] & 0xff000000) >> 24;
26313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] &= 0xff;
26413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
26513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (1 == minMag)
26613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
26713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        const unsigned x1 = MIN2(width - 1, x0 + 1), y1 = MIN2(height - 1, y0 + 1);
26813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Vec4<int> samples[4] = {0};
26913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 0), data, face * width * height + y0 * width + x0);
27013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 0);
27113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 1), data, face * width * height + y0 * width + x1);
27213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 1);
27313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 2), data, face * width * height + y1 * width + x1);
27413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 2);
27513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        PointSample<format>((unsigned *)(samples + 3), data, face * width * height + y1 * width + x0);
27613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ToIntVec(samples + 3);
27713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
27813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Lerp(samples + 0, samples + 1, xLerp, samples + 0);
27913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Lerp(samples + 3, samples + 2, xLerp, samples + 3);
28013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        Lerp(samples + 0, samples + 3, yLerp, (Vec4<int> *)sample);
28113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
28213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else
28313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        assert(0);
28413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
28513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (Fixed0 == output) // i32 non vector
28613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] = (sample[3] << 24) | (sample[2] << 16) | (sample[1] << 8) | sample[0];
28713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (Fixed8 == output) // 4 x i32
28813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        ; // do nothing
28913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (Fixed16 == output) // 4 x i32
29013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
29113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        sample[0] <<= 8; sample[1] <<= 8; sample[2] <<= 8; sample[3] <<= 8;
29213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
29313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else if (Float == output) // 4 x float
29413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
29513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        float * fsample = (float *)sample;
29613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        fsample[0] = sample[0] / 255.0f; fsample[1] = sample[1] / 255.0f;
29713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        fsample[2] = sample[2] / 255.0f; fsample[3] = sample[3] / 255.0f;
29813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
29913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
30013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
30113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
30213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRY(target,format,output,filter,wrapS,wrapT) \
30313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{ #target"_"#format"_"#output"_"#filter"_"#wrapS"_"#wrapT, \
30413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Litarget<GGL_PIXEL_FORMAT_##format, output, filter, wrapS, wrapT> },
30513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
30613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRY_WRAPT(target,format,output,minMag,wrapS) \
30713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY(target,format,output,minMag,wrapS,0) \
30813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY(target,format,output,minMag,wrapS,1) \
30913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY(target,format,output,minMag,wrapS,2)
31013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
31113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRY_WRAPS(target,format,output,minMag) \
31213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_WRAPT(target,format,output,minMag,0) \
31313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_WRAPT(target,format,output,minMag,1) \
31413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_WRAPT(target,format,output,minMag,2)
31513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
31613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRY_FILTER(target,format,output) \
31713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_WRAPS(target,format,output,0) \
31813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_WRAPS(target,format,output,1)
31913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
32013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRY_OUTPUT(target,format) \
32113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_FILTER(target,format,Float) \
32213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_FILTER(target,format,Fixed16) \
32313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_FILTER(target,format,Fixed8) \
32413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_FILTER(target,format,Fixed0)
32513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
32613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRY_FORMAT(target) \
32713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_OUTPUT(target,RGBA_8888) \
32813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_OUTPUT(target,RGBX_8888) \
32913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_OUTPUT(target,RGB_565) \
33013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_OUTPUT(target,UNKNOWN)
33113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
33213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#define TEXTURE_FUNCTION_ENTRIES \
33313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_FORMAT(tex2d) \
33413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid LiTEXTURE_FUNCTION_ENTRY_FORMAT(texcube)
33513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
33613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic struct TextureFunctionMapping
33713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
33813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    const char * name;
33913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    void (* function)(unsigned sample[4], const float tex_coord[4], const unsigned int tex_id);
34013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li} textureFunctionMapping [] = { TEXTURE_FUNCTION_ENTRIES };
34113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
34213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
34313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#undef TEXTURE_FUNCTION_ENTRY
34413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
34513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#endif //#if !USE_LLVM_TEXTURE_SAMPLER
34613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
34713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#if USE_LLVM_EXECUTIONENGINE && !USE_LLVM_TEXTURE_SAMPLER
34813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
34913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Livoid DeclareTextureFunctions(llvm::Module * mod)
35013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
35113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	llvm::LLVMContext & llvm_ctx = mod->getContext();
35213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
35313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    std::vector<const llvm::Type*> funcArgs;
35413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    llvm::VectorType *vectorType = llvm::VectorType::get(llvm::Type::getFloatTy(llvm_ctx), 4);
35513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    llvm::PointerType * vectorPtr = llvm::PointerType::get(vectorType, 0);
35613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
35713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    funcArgs.push_back(vectorPtr);
35813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	funcArgs.push_back(vectorPtr);
35913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	funcArgs.push_back(llvm::Type::getInt32Ty(llvm_ctx));
36013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li	// void function(float[4], const float[4], unsigned)
36113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
36213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    llvm::FunctionType *functionType = llvm::FunctionType::get(llvm::Type::getVoidTy(llvm_ctx),
36313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li                                                   funcArgs,
36413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li                                                   false);
36513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
36613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    for (unsigned i = 0; i < sizeof(textureFunctionMapping) / sizeof(*textureFunctionMapping); i++)
36713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
36813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        llvm::Function * func = llvm::cast<llvm::Function>(
36913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        mod->getOrInsertFunction(textureFunctionMapping[i].name, functionType));
37013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        func->setLinkage(llvm::GlobalValue::ExternalLinkage);
37113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        func->setCallingConv(llvm::CallingConv::C);
37213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
37313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
37413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
37513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Livoid AddTextureFunctionMappings(llvm::Module * mod, llvm::ExecutionEngine * ee)
37613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
37713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (mod->getFunction("tex2d_soa"))
37813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        assert(0);//ee->addGlobalMapping(func, (void *)tex2d_soa);
37913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
38013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    for (unsigned i = 0; i < sizeof(textureFunctionMapping) / sizeof(*textureFunctionMapping); i++)
38113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
38213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        llvm::Function * function = mod->getFunction(textureFunctionMapping[i].name);
38313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        if (function)
38413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            ee->updateGlobalMapping(function, (void *)textureFunctionMapping[i].function);
38513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
38613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
38713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#endif // #if USE_LLVM_EXECUTIONENGINE && !USE_LLVM_TEXTURE_SAMPLER
38813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
38913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void SetSampler(GGLInterface * iface, const unsigned sampler, GGLTexture * texture)
39013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
39113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    assert(GGL_MAXCOMBINEDTEXTUREIMAGEUNITS > sampler);
39213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    GGL_GET_CONTEXT(ctx, iface);
39313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (!texture)
39413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        SetShaderVerifyFunctions(iface);
3952ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li    else if (ctx->state.textureState.textures[sampler].format != texture->format)
39613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        SetShaderVerifyFunctions(iface);
3972ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li    else if (ctx->state.textureState.textures[sampler].wrapS != texture->wrapS)
39813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        SetShaderVerifyFunctions(iface);
3992ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li    else if (ctx->state.textureState.textures[sampler].wrapT != texture->wrapT)
40013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        SetShaderVerifyFunctions(iface);
4012ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li    else if (ctx->state.textureState.textures[sampler].minFilter != texture->minFilter)
40213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        SetShaderVerifyFunctions(iface);
4032ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li    else if (ctx->state.textureState.textures[sampler].magFilter != texture->magFilter)
40413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li        SetShaderVerifyFunctions(iface);
40513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
40613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    if (texture)
40713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
4082ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textures[sampler] = *texture; // shallow copy, data pointed to must remain valid
4092ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        //ctx->state.textureState.textureData[sampler] = texture->levels[0];
4102ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textureData[sampler] = texture->levels;
4112ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textureDimensions[sampler * 2] = texture->width;
4122ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textureDimensions[sampler * 2 + 1] = texture->height;
41313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
41413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    else
41513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    {
4162ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        memset(ctx->state.textureState.textures + sampler, 0, sizeof(ctx->state.textureState.textures[sampler]));
4172ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textureData[sampler] = NULL;
4182ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textureDimensions[sampler * 2] = 0;
4192ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li        ctx->state.textureState.textureDimensions[sampler * 2 + 1] = 0;
42013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    }
42113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
42213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
42313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Livoid InitializeTextureFunctions(GGLInterface * iface)
42413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
42513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li    iface->SetSampler = SetSampler;
42613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}