OSDN Git Service

texelFetch implementation
authorMeng-Lin Wu <marleymoo@google.com>
Tue, 7 Jun 2016 20:15:12 +0000 (16:15 -0400)
committerMeng-Lin Wu <marleymoo@google.com>
Mon, 13 Jun 2016 21:45:14 +0000 (21:45 +0000)
Passes all texelFetch and texelFetchOffset tests in dEQP.

Change-Id: Ic212d326d1c062f1947696e6963fef300b7737f1
Reviewed-on: https://swiftshader-review.googlesource.com/5512
Tested-by: Meng-Lin Wu <marleymoo@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/Renderer/Sampler.cpp
src/Renderer/Sampler.hpp
src/Shader/PixelProgram.cpp
src/Shader/PixelProgram.hpp
src/Shader/SamplerCore.cpp
src/Shader/SamplerCore.hpp
src/Shader/VertexProgram.cpp
src/Shader/VertexProgram.hpp

index 93cca30..c6cec5e 100644 (file)
@@ -76,8 +76,8 @@ namespace sw
 
                texture.baseLevel = 0;
                texture.maxLevel = 1000;
-               texture.maxLod = 1000;
-               texture.minLod = -1000;
+               texture.maxLod = MIPMAP_LEVELS - 2;     // Trilinear accesses lod+1
+               texture.minLod = 0;
        }
 
        Sampler::~Sampler()
@@ -351,12 +351,12 @@ namespace sw
 
        void Sampler::setMinLod(float minLod)
        {
-               texture.minLod = minLod;
+               texture.minLod = clamp(minLod, 0.0f, (float)(MIPMAP_LEVELS - 2));
        }
 
        void Sampler::setMaxLod(float maxLod)
        {
-               texture.maxLod = maxLod;
+               texture.maxLod = clamp(maxLod, 0.0f, (float)(MIPMAP_LEVELS - 2));
        }
 
        void Sampler::setFilterQuality(FilterType maximumFilterQuality)
index 032bf58..56841a8 100644 (file)
@@ -119,8 +119,9 @@ namespace sw
                ADDRESSING_MIRRORONCE,
                ADDRESSING_BORDER,
                ADDRESSING_LAYER,
+               ADDRESSING_TEXELFETCH,
 
-               ADDRESSING_LAST = ADDRESSING_LAYER
+               ADDRESSING_LAST = ADDRESSING_TEXELFETCH
        };
 
        enum SwizzleType : unsigned int
index af9fca0..be4bf0b 100644 (file)
@@ -675,13 +675,13 @@ namespace sw
                }
        }
 
-       void PixelProgram::sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, bool project, SamplerMethod method, bool hasOffset)
+       void PixelProgram::sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, unsigned int options)
        {
                Vector4f tmp;
 
                if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID)
                {
-                       sampleTexture(tmp, sampler.index, u, v, w, q, dsx, dsy, offset, project, method, hasOffset);
+                       sampleTexture(tmp, sampler.index, u, v, w, q, dsx, dsy, offset, method, options);
                }
                else
                {
@@ -693,7 +693,7 @@ namespace sw
                                {
                                        If(index == i)
                                        {
-                                               sampleTexture(tmp, i, u, v, w, q, dsx, dsy, offset, project, method, hasOffset);
+                                               sampleTexture(tmp, i, u, v, w, q, dsx, dsy, offset, method, options);
                                                // FIXME: When the sampler states are the same, we could use one sampler and just index the texture
                                        }
                                }
@@ -706,7 +706,7 @@ namespace sw
                c.w = tmp[(sampler.swizzle >> 6) & 0x3];
        }
 
-       void PixelProgram::sampleTexture(Vector4f &c, int samplerIndex, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, bool project, SamplerMethod method, bool hasOffset)
+       void PixelProgram::sampleTexture(Vector4f &c, int samplerIndex, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, unsigned int options)
        {
                #if PERF_PROFILE
                        Long texTime = Ticks();
@@ -714,9 +714,9 @@ namespace sw
 
                Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture);
 
-               if(!project)
+               if(!(options & Project))
                {
-                       sampler[samplerIndex]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, offset, method, hasOffset);
+                       sampler[samplerIndex]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, offset, options, method);
                }
                else
                {
@@ -726,7 +726,7 @@ namespace sw
                        Float4 v_q = v * rq;
                        Float4 w_q = w * rq;
 
-                       sampler[samplerIndex]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, offset, method, hasOffset);
+                       sampler[samplerIndex]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, offset, options, method);
                }
 
                #if PERF_PROFILE
@@ -1107,47 +1107,47 @@ namespace sw
 
        void PixelProgram::TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src0, project, bias ? Bias : Implicit, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src0, bias ? Bias : Implicit, project ? Project : None);
        }
 
        void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src2, project, bias ? Bias : Implicit, true);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src2, bias ? Bias : Implicit, project ? (Project | Offset) : Offset);
        }
 
        void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool project, bool bias)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, offset, project, Lod, true);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, offset, Lod, project ? (Project | Offset) : Offset);
        }
 
        void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
        {
-               UNIMPLEMENTED();
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, Float4(As<Int4>(src2.x)), src0, src0, src0, Lod, Fetch);
        }
 
        void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &offset)
        {
-               UNIMPLEMENTED();
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, Float4(As<Int4>(src2.x)), src0, src0, offset, Lod, Fetch | Offset);
        }
 
        void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, src0, false, Grad, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, src0, Grad, None);
        }
 
        void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, offset, false, Grad, true);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, offset, Grad, Offset);
        }
 
        void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, src0, project, Grad, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, src0, Grad, project ? Project : None);
        }
 
        void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src0, project, Lod, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src0, Lod, project ? Project : None);
        }
 
        void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
index 3d8d41f..bad1538 100644 (file)
@@ -82,8 +82,8 @@ namespace sw
                Int4 enableContinue;
                Int4 enableLeave;
 
-               void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, bool project, SamplerMethod method, bool hasOffset);
-               void sampleTexture(Vector4f &c, int samplerIndex, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, bool project, SamplerMethod method, bool hasOffset);
+               void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, unsigned int options);
+               void sampleTexture(Vector4f &c, int samplerIndex, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, unsigned int options);
 
                // Raster operations
                void clampColor(Vector4f oC[RENDERTARGETS]);
index 9e2179b..e2ca316 100644 (file)
@@ -54,12 +54,12 @@ namespace sw
        {
        }
 
-       void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method)
+       void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy)
        {
-               sampleTexture(texture, c, u, v, w, q, dsx, dsy, dsx, false, method, true);
+               sampleTexture(texture, c, u, v, w, q, dsx, dsy, dsx, None, Implicit, true);
        }
 
-       void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, bool hasOffset, SamplerMethod method, bool fixed12)
+       void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, unsigned int options, SamplerMethod method, bool fixed12)
        {
                #if PERF_PROFILE
                        AddAtomic(Pointer<Long>(&profiler.texOperations), 4);
@@ -124,13 +124,13 @@ namespace sw
 
                        if(!hasFloatTexture())
                        {
-                               sampleFilter(texture, c, uuuu, vvvv, wwww, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, method);
+                               sampleFilter(texture, c, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, options, method);
                        }
                        else
                        {
                                Vector4f cf;
 
-                               sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, method);
+                               sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, options, method);
 
                                convertFixed12(c, cf);
                        }
@@ -293,7 +293,7 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, bool hasOffset)
+       void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, unsigned int options, SamplerMethod method)
        {
                #if PERF_PROFILE
                        AddAtomic(Pointer<Long>(&profiler.texOperations), 4);
@@ -350,13 +350,13 @@ namespace sw
                                        computeLod3D(texture, lod, uuuu, vvvv, wwww, q.x, dsx, dsy, method);
                                }
 
-                               sampleFloatFilter(texture, c, uuuu, vvvv, wwww, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, method);
+                               sampleFloatFilter(texture, c, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, options, method);
                        }
                        else
                        {
                                Vector4s cs;
 
-                               sampleTexture(texture, cs, u, v, w, q, dsx, dsy, offset, hasOffset, method, false);
+                               sampleTexture(texture, cs, u, v, w, q, dsx, dsy, offset, options, method, false);
 
                                for(int component = 0; component < textureComponentCount(); component++)
                                {
@@ -609,15 +609,20 @@ namespace sw
                return uvw;
        }
 
-       void SamplerCore::sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method)
+       void SamplerCore::sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], unsigned int options, SamplerMethod method)
        {
-               sampleAniso(texture, c, u, v, w, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, false, method);
+               sampleAniso(texture, c, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, false, options, method);
+
+               if(options & Fetch)
+               {
+                       return;
+               }
 
                if(state.mipmapFilter > MIPMAP_POINT)
                {
                        Vector4s cc;
 
-                       sampleAniso(texture, cc, u, v, w, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, true, method);
+                       sampleAniso(texture, cc, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, true, options, method);
 
                        lod *= Float(1 << 16);
 
@@ -705,11 +710,11 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method)
+       void SamplerCore::sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, unsigned int options, SamplerMethod method)
        {
-               if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod)
+               if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod || options & Fetch)
                {
-                       sampleQuad(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
+                       sampleQuad(texture, c, u, v, w, offset, lod, face, secondLOD, options);
                }
                else
                {
@@ -740,7 +745,7 @@ namespace sw
 
                        Do
                        {
-                               sampleQuad(texture, c, u0, v0, w, offset, hasOffset, lod, face, secondLOD);
+                               sampleQuad(texture, c, u0, v0, w, offset, lod, face, secondLOD, options);
 
                                u0 += du;
                                v0 += dv;
@@ -761,19 +766,19 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD)
+       void SamplerCore::sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options)
        {
                if(state.textureType != TEXTURE_3D)
                {
-                       sampleQuad2D(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
+                       sampleQuad2D(texture, c, u, v, w, offset, lod, face, secondLOD, options);
                }
                else
                {
-                       sample3D(texture, c, u, v, w, offset, hasOffset, lod, secondLOD);
+                       sample3D(texture, c, u, v, w, offset, lod, secondLOD, options);
                }
        }
 
-       void SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD)
+       void SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options)
        {
                int componentCount = textureComponentCount();
                bool gather = state.textureFilter == FILTER_GATHER;
@@ -783,13 +788,15 @@ namespace sw
 
                selectMipmap(texture, buffer, mipmap, lod, face, secondLOD);
 
-               Short4 uuuu = address(u, state.addressingModeU, mipmap);
-               Short4 vvvv = address(v, state.addressingModeV, mipmap);
-               Short4 wwww = address(w, state.addressingModeW, mipmap);
+               bool texelFetch = (options & Fetch) != 0;
+
+               Short4 uuuu = texelFetch ? Short4(As<Int4>(u)) : address(u, state.addressingModeU, mipmap);
+               Short4 vvvv = texelFetch ? Short4(As<Int4>(v)) : address(v, state.addressingModeV, mipmap);
+               Short4 wwww = texelFetch ? Short4(As<Int4>(w)) : address(w, state.addressingModeW, mipmap);
 
-               if(state.textureFilter == FILTER_POINT)
+               if(state.textureFilter == FILTER_POINT || texelFetch)
                {
-                       sampleTexel(c, uuuu, vvvv, wwww, offset, hasOffset, mipmap, buffer);
+                       sampleTexel(c, uuuu, vvvv, wwww, offset, mipmap, buffer, options);
                }
                else
                {
@@ -803,10 +810,10 @@ namespace sw
                        Short4 uuuu1 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 2 : +1, lod);
                        Short4 vvvv1 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 2 : +1, lod);
 
-                       sampleTexel(c0, uuuu0, vvvv0, wwww, offset, hasOffset, mipmap, buffer);
-                       sampleTexel(c1, uuuu1, vvvv0, wwww, offset, hasOffset, mipmap, buffer);
-                       sampleTexel(c2, uuuu0, vvvv1, wwww, offset, hasOffset, mipmap, buffer);
-                       sampleTexel(c3, uuuu1, vvvv1, wwww, offset, hasOffset, mipmap, buffer);
+                       sampleTexel(c0, uuuu0, vvvv0, wwww, offset, mipmap, buffer, options);
+                       sampleTexel(c1, uuuu1, vvvv0, wwww, offset, mipmap, buffer, options);
+                       sampleTexel(c2, uuuu0, vvvv1, wwww, offset, mipmap, buffer, options);
+                       sampleTexel(c3, uuuu1, vvvv1, wwww, offset, mipmap, buffer, options);
 
                        if(!gather)   // Blend
                        {
@@ -978,7 +985,7 @@ namespace sw
                }
        }
 
-       void SamplerCore::sample3D(Pointer<Byte> &texture, Vector4s &c_, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, bool hasOffset, Float &lod, bool secondLOD)
+       void SamplerCore::sample3D(Pointer<Byte> &texture, Vector4s &c_, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, Float &lod, bool secondLOD, unsigned int options)
        {
                int componentCount = textureComponentCount();
 
@@ -988,13 +995,15 @@ namespace sw
 
                selectMipmap(texture, buffer, mipmap, lod, face, secondLOD);
 
-               Short4 uuuu = address(u_, state.addressingModeU, mipmap);
-               Short4 vvvv = address(v_, state.addressingModeV, mipmap);
-               Short4 wwww = address(w_, state.addressingModeW, mipmap);
+               bool texelFetch = (options & Fetch) != 0;
 
-               if(state.textureFilter == FILTER_POINT)
+               Short4 uuuu = texelFetch ? Short4(As<Int4>(u_)) : address(u_, state.addressingModeU, mipmap);
+               Short4 vvvv = texelFetch ? Short4(As<Int4>(v_)) : address(v_, state.addressingModeV, mipmap);
+               Short4 wwww = texelFetch ? Short4(As<Int4>(w_)) : address(w_, state.addressingModeW, mipmap);
+
+               if(state.textureFilter == FILTER_POINT || texelFetch)
                {
-                       sampleTexel(c_, uuuu, vvvv, wwww, offset, hasOffset, mipmap, buffer);
+                       sampleTexel(c_, uuuu, vvvv, wwww, offset, mipmap, buffer, options);
                }
                else
                {
@@ -1078,7 +1087,7 @@ namespace sw
                                {
                                        for(int k = 0; k < 2; k++)
                                        {
-                                               sampleTexel(c[i][j][k], u[i][j][k], v[i][j][k], s[i][j][k], offset, hasOffset, mipmap, buffer);
+                                               sampleTexel(c[i][j][k], u[i][j][k], v[i][j][k], s[i][j][k], offset, mipmap, buffer, options);
 
                                                if(componentCount >= 1) { if(hasUnsignedTextureComponent(0)) c[i][j][k].x = MulHigh(As<UShort4>(c[i][j][k].x), f[1 - i][1 - j][1 - k]); else c[i][j][k].x = MulHigh(c[i][j][k].x, fs[1 - i][1 - j][1 - k]); }
                                                if(componentCount >= 2) { if(hasUnsignedTextureComponent(1)) c[i][j][k].y = MulHigh(As<UShort4>(c[i][j][k].y), f[1 - i][1 - j][1 - k]); else c[i][j][k].y = MulHigh(c[i][j][k].y, fs[1 - i][1 - j][1 - k]); }
@@ -1109,15 +1118,20 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method)
+       void SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], unsigned int options, SamplerMethod method)
        {
-               sampleFloatAniso(texture, c, u, v, w, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, false, method);
+               sampleFloatAniso(texture, c, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, false, options, method);
+       
+               if(options & Fetch)
+               {
+                       return;
+               }
 
                if(state.mipmapFilter > MIPMAP_POINT)
                {
                        Vector4f cc;
 
-                       sampleFloatAniso(texture, cc, u, v, w, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, true, method);
+                       sampleFloatAniso(texture, cc, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, true, options, method);
 
                        Float4 lod4 = Float4(Frac(lod));
 
@@ -1184,11 +1198,11 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method)
+       void SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, unsigned int options, SamplerMethod method)
        {
-               if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod)
+               if (state.textureFilter != FILTER_ANISOTROPIC || method == Lod || options & Fetch)
                {
-                       sampleFloat(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
+                       sampleFloat(texture, c, u, v, w, offset, lod, face, secondLOD, options);
                }
                else
                {
@@ -1217,7 +1231,7 @@ namespace sw
 
                        Do
                        {
-                               sampleFloat(texture, c, u0, v0, w, offset, hasOffset, lod, face, secondLOD);
+                               sampleFloat(texture, c, u0, v0, w, offset, lod, face, secondLOD, options);
 
                                u0 += du;
                                v0 += dv;
@@ -1238,19 +1252,19 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD)
+       void SamplerCore::sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options)
        {
                if(state.textureType != TEXTURE_3D)
                {
-                       sampleFloat2D(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
+                       sampleFloat2D(texture, c, u, v, w, offset, lod, face, secondLOD, options);
                }
                else
                {
-                       sampleFloat3D(texture, c, u, v, w, offset, hasOffset, lod, secondLOD);
+                       sampleFloat3D(texture, c, u, v, w, offset, lod, secondLOD, options);
                }
        }
 
-       void SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD)
+       void SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options)
        {
                int componentCount = textureComponentCount();
                bool gather = state.textureFilter == FILTER_GATHER;
@@ -1260,13 +1274,15 @@ namespace sw
 
                selectMipmap(texture, buffer, mipmap, lod, face, secondLOD);
 
-               Short4 uuuu = address(u, state.addressingModeU, mipmap);
-               Short4 vvvv = address(v, state.addressingModeV, mipmap);
-               Short4 wwww = address(w, state.addressingModeW, mipmap);
+               bool texelFetch = (options & Fetch) != 0;
+
+               Short4 uuuu = texelFetch ? Short4(As<Int4>(u)) : address(u, state.addressingModeU, mipmap);
+               Short4 vvvv = texelFetch ? Short4(As<Int4>(v)) : address(v, state.addressingModeV, mipmap);
+               Short4 wwww = texelFetch ? Short4(As<Int4>(w)) : address(w, state.addressingModeW, mipmap);
 
-               if(state.textureFilter == FILTER_POINT)
+               if(state.textureFilter == FILTER_POINT || texelFetch)
                {
-                       sampleTexel(c, uuuu, vvvv, wwww, offset, hasOffset, w, mipmap, buffer);
+                       sampleTexel(c, uuuu, vvvv, wwww, offset, w, mipmap, buffer, options);
                }
                else
                {
@@ -1280,10 +1296,10 @@ namespace sw
                        Short4 uuuu1 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 2 : +1, lod);
                        Short4 vvvv1 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 2 : +1, lod);
 
-                       sampleTexel(c0, uuuu0, vvvv0, wwww, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c1, uuuu1, vvvv0, wwww, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c2, uuuu0, vvvv1, wwww, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c3, uuuu1, vvvv1, wwww, offset, hasOffset, w, mipmap, buffer);
+                       sampleTexel(c0, uuuu0, vvvv0, wwww, offset, w, mipmap, buffer, options);
+                       sampleTexel(c1, uuuu1, vvvv0, wwww, offset, w, mipmap, buffer, options);
+                       sampleTexel(c2, uuuu0, vvvv1, wwww, offset, w, mipmap, buffer, options);
+                       sampleTexel(c3, uuuu1, vvvv1, wwww, offset, w, mipmap, buffer, options);
 
                        if(!gather)   // Blend
                        {
@@ -1316,7 +1332,7 @@ namespace sw
                }
        }
 
-       void SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, bool secondLOD)
+       void SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, unsigned int options)
        {
                int componentCount = textureComponentCount();
 
@@ -1326,13 +1342,15 @@ namespace sw
 
                selectMipmap(texture, buffer, mipmap, lod, face, secondLOD);
 
-               Short4 uuuu = address(u, state.addressingModeU, mipmap);
-               Short4 vvvv = address(v, state.addressingModeV, mipmap);
-               Short4 wwww = address(w, state.addressingModeW, mipmap);
+               bool texelFetch = (options & Fetch) != 0;
 
-               if(state.textureFilter == FILTER_POINT)
+               Short4 uuuu = texelFetch ? Short4(As<Int4>(u)) : address(u, state.addressingModeU, mipmap);
+               Short4 vvvv = texelFetch ? Short4(As<Int4>(v)) : address(v, state.addressingModeV, mipmap);
+               Short4 wwww = texelFetch ? Short4(As<Int4>(w)) : address(w, state.addressingModeW, mipmap);
+
+               if(state.textureFilter == FILTER_POINT || texelFetch)
                {
-                       sampleTexel(c, uuuu, vvvv, wwww, offset, hasOffset, w, mipmap, buffer);
+                       sampleTexel(c, uuuu, vvvv, wwww, offset, w, mipmap, buffer, options);
                }
                else
                {
@@ -1352,14 +1370,14 @@ namespace sw
                        Short4 vvvv1 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, +1, lod);
                        Short4 wwww1 = offsetSample(wwww, mipmap, OFFSET(Mipmap,wHalf), state.addressingModeW == ADDRESSING_WRAP, +1, lod);
 
-                       sampleTexel(c0, uuuu0, vvvv0, wwww0, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c1, uuuu1, vvvv0, wwww0, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c2, uuuu0, vvvv1, wwww0, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c3, uuuu1, vvvv1, wwww0, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c4, uuuu0, vvvv0, wwww1, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c5, uuuu1, vvvv0, wwww1, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c6, uuuu0, vvvv1, wwww1, offset, hasOffset, w, mipmap, buffer);
-                       sampleTexel(c7, uuuu1, vvvv1, wwww1, offset, hasOffset, w, mipmap, buffer);
+                       sampleTexel(c0, uuuu0, vvvv0, wwww0, offset, w, mipmap, buffer, options);
+                       sampleTexel(c1, uuuu1, vvvv0, wwww0, offset, w, mipmap, buffer, options);
+                       sampleTexel(c2, uuuu0, vvvv1, wwww0, offset, w, mipmap, buffer, options);
+                       sampleTexel(c3, uuuu1, vvvv1, wwww0, offset, w, mipmap, buffer, options);
+                       sampleTexel(c4, uuuu0, vvvv0, wwww1, offset, w, mipmap, buffer, options);
+                       sampleTexel(c5, uuuu1, vvvv0, wwww1, offset, w, mipmap, buffer, options);
+                       sampleTexel(c6, uuuu0, vvvv1, wwww1, offset, w, mipmap, buffer, options);
+                       sampleTexel(c7, uuuu1, vvvv1, wwww1, offset, w, mipmap, buffer, options);
 
                        // Fractions
                        Float4 fu = Frac(Float4(As<UShort4>(uuuu0)) * *Pointer<Float4>(mipmap + OFFSET(Mipmap,fWidth)));
@@ -1463,11 +1481,11 @@ namespace sw
                }
                else
                {
-                       lod = lodBias + *Pointer<Float>(texture + OFFSET(Texture,LOD));
+                       lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
                }
 
-               lod = Max(lod, 0.0f);
-               lod = Min(lod, Float(MIPMAP_LEVELS - 2));   // Trilinear accesses lod+1
+               lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
+               lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
        }
 
        void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &s, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method)
@@ -1522,11 +1540,11 @@ namespace sw
                }
                else
                {
-                       lod = lodBias + *Pointer<Float>(texture + OFFSET(Texture,LOD));
+                       lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
                }
 
-               lod = Max(lod, 0.0f);
-               lod = Min(lod, Float(MIPMAP_LEVELS - 2));   // Trilinear accesses lod+1
+               lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
+               lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
        }
 
        void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method)
@@ -1589,11 +1607,11 @@ namespace sw
                        }
                        else
                        {
-                               lod = lodBias + *Pointer<Float>(texture + OFFSET(Texture,LOD));
+                               lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
                        }
 
-                       lod = Max(lod, Float(0.0f));    // FIXME
-                       lod = Min(lod, Float(MIPMAP_LEVELS - 2));   // Trilinear accesses lod+1
+                       lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
+                       lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
                }
        }
 
@@ -1657,7 +1675,7 @@ namespace sw
                Int4 tmp = Int4(As<UShort4>(uvw));
                tmp = tmp + As<Int4>(offset);
 
-               switch(mode)
+               switch (mode)
                {
                case AddressingMode::ADDRESSING_WRAP:
                        tmp = (tmp + whd * Int4(-MIN_PROGRAM_TEXEL_OFFSET)) % whd;
@@ -1666,7 +1684,9 @@ namespace sw
                case AddressingMode::ADDRESSING_MIRROR:
                case AddressingMode::ADDRESSING_MIRRORONCE:
                case AddressingMode::ADDRESSING_BORDER: // FIXME: Implement and test ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE, ADDRESSING_BORDER
-                       tmp = Min(Max(tmp, Int4(0)), whd - Int4(1)); 
+                       tmp = Min(Max(tmp, Int4(0)), whd - Int4(1));
+                       break;
+               case ADDRESSING_TEXELFETCH:
                        break;
                default:
                        ASSERT(false);
@@ -1675,29 +1695,40 @@ namespace sw
                return As<Short4>(UShort4(tmp));
        }
 
-       void SamplerCore::computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, bool hasOffset, const Pointer<Byte> &mipmap)
+       void SamplerCore::computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, unsigned int options)
        {
                Short4 uuu2;
 
+               bool texelFetch = (options & Fetch) != 0;
+               bool hasOffset = (options & Offset) != 0;
+
                if(!state.hasNPOTTexture && !hasFloatTexture() && !hasOffset)
                {
-                       vvvv = As<UShort4>(vvvv) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,vFrac));
+                       if(!texelFetch)
+                       {
+                               vvvv = As<UShort4>(vvvv) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap, vFrac));
+                       }
                        uuu2 = uuuu;
                        uuuu = As<Short4>(UnpackLow(uuuu, vvvv));
                        uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv));
-                       uuuu = As<Short4>(As<UInt2>(uuuu) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,uFrac)));
-                       uuu2 = As<Short4>(As<UInt2>(uuu2) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,uFrac)));
+                       if(!texelFetch)
+                       {
+                               uuuu = As<Short4>(As<UInt2>(uuuu) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap, uFrac)));
+                               uuu2 = As<Short4>(As<UInt2>(uuu2) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap, uFrac)));
+                       }
                }
                else
                {
-                       uuuu = MulHigh(As<UShort4>(uuuu), *Pointer<UShort4>(mipmap + OFFSET(Mipmap,width)));
-                       vvvv = MulHigh(As<UShort4>(vvvv), *Pointer<UShort4>(mipmap + OFFSET(Mipmap,height)));
+                       if(!texelFetch)
+                       {
+                               uuuu = MulHigh(As<UShort4>(uuuu), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, width)));
+                               vvvv = MulHigh(As<UShort4>(vvvv), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, height)));
+                       }
                        if(hasOffset)
                        {
-                               uuuu = applyOffset(uuuu, offset.x, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, width))), state.addressingModeU);
-                               vvvv = applyOffset(vvvv, offset.y, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, height))), state.addressingModeV);
+                               uuuu = applyOffset(uuuu, offset.x, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, width))), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU);
+                               vvvv = applyOffset(vvvv, offset.y, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, height))), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
                        }
-
                        uuu2 = uuuu;
                        uuuu = As<Short4>(UnpackLow(uuuu, vvvv));
                        uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv));
@@ -1709,10 +1740,13 @@ namespace sw
                {
                        if(state.textureType != TEXTURE_2D_ARRAY)
                        {
-                               wwww = MulHigh(As<UShort4>(wwww), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth)));
+                               if(!texelFetch)
+                               {
+                                       wwww = MulHigh(As<UShort4>(wwww), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth)));
+                               }
                                if(hasOffset)
                                {
-                                       wwww = applyOffset(wwww, offset.z, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth))), state.addressingModeW);
+                                       wwww = applyOffset(wwww, offset.z, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth))), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
                                }
                        }
                        Short4 www2 = wwww;
@@ -1728,13 +1762,29 @@ namespace sw
                index[1] = Extract(As<Int2>(uuuu), 1);
                index[2] = Extract(As<Int2>(uuu2), 0);
                index[3] = Extract(As<Int2>(uuu2), 1);
+
+               if(texelFetch)
+               {
+                       Int size = Int(*Pointer<Int>(mipmap + OFFSET(Mipmap, sliceP)));
+                       if((state.textureType == TEXTURE_3D) || (state.textureType == TEXTURE_2D_ARRAY))
+                       {
+                               size *= Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, depth)));
+                       }
+                       Int min = Int(0);
+                       Int max = size - Int(1);
+
+                       for(int i = 0; i < 4; i++)
+                       {
+                               index[i] = Min(Max(index[i], min), max);
+                       }
+               }
        }
 
-       void SamplerCore::sampleTexel(Vector4s &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, bool hasOffset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4])
+       void SamplerCore::sampleTexel(Vector4s &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], unsigned int options)
        {
                Int index[4];
 
-               computeIndices(index, uuuu, vvvv, wwww, offset, hasOffset, mipmap);
+               computeIndices(index, uuuu, vvvv, wwww, offset, mipmap, options);
 
                int f0 = state.textureType == TEXTURE_CUBE ? 0 : 0;
                int f1 = state.textureType == TEXTURE_CUBE ? 1 : 0;
@@ -1970,7 +2020,7 @@ namespace sw
                        c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
                        UShort4 Y = As<UShort4>(Unpack(As<Byte4>(c0)));
 
-                       computeIndices(index, uuuu, vvvv, wwww, offset, hasOffset, mipmap + sizeof(Mipmap));
+                       computeIndices(index, uuuu, vvvv, wwww, offset, mipmap + sizeof(Mipmap), options);
                        c0 = Int(*Pointer<Byte>(buffer[1] + index[0]));
                        c1 = Int(*Pointer<Byte>(buffer[1] + index[1]));
                        c2 = Int(*Pointer<Byte>(buffer[1] + index[2]));
@@ -2007,11 +2057,11 @@ namespace sw
                else ASSERT(false);
        }
 
-       void SamplerCore::sampleTexel(Vector4f &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, bool hasOffset, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4])
+       void SamplerCore::sampleTexel(Vector4f &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], unsigned int options)
        {
                Int index[4];
 
-               computeIndices(index, uuuu, vvvv, wwww, offset, hasOffset, mipmap);
+               computeIndices(index, uuuu, vvvv, wwww, offset, mipmap, options);
 
                int f0 = state.textureType == TEXTURE_CUBE ? 0 : 0;
                int f1 = state.textureType == TEXTURE_CUBE ? 1 : 0;
index ba24444..9bd07c2 100644 (file)
@@ -25,7 +25,15 @@ namespace sw
                Implicit,
                Bias,
                Lod,
-               Grad,
+               Grad
+       };
+
+       enum TextureFunction\r
+       {\r
+               None = 0x00,\r
+               Project = 0x01,\r
+               Offset = 0x02,\r
+               Fetch = 0x04\r
        };
 
        class SamplerCore
@@ -33,34 +41,34 @@ namespace sw
        public:
                SamplerCore(Pointer<Byte> &r, const Sampler::State &state);
 
-               void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method = Implicit);
-               void sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method = Implicit, bool hasOffset = false);
+               void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy);
+               void sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, unsigned int options, SamplerMethod method);
                void textureSize(Pointer<Byte> &mipmap, Vector4f &size, Float4 &lod);
 
        private:
-               void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, bool hasOffset, SamplerMethod method, bool fixed12);
+               void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, unsigned int options, SamplerMethod method, bool fixed12);
 
                void border(Short4 &mask, Float4 &coordinates);
                void border(Int4 &mask, Float4 &coordinates);
                Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
-               void sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method);
-               void sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method);
-               void sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD);
-               void sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD);
-               void sample3D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, bool secondLOD);
-               void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method);
-               void sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method);
-               void sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD);
-               void sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, Int face[4], bool secondLOD);
-               void sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, bool secondLOD);
+               void sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], unsigned int options, SamplerMethod method);
+               void sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, unsigned int options, SamplerMethod method);
+               void sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options);
+               void sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options);
+               void sample3D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, unsigned int options);
+               void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], unsigned int options, SamplerMethod method);
+               void sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, unsigned int options, SamplerMethod method);
+               void sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options);
+               void sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, unsigned int options);
+               void sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, unsigned int options);
                void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);
                void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &x, Float4 &y, Float4 &z, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);
                void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method);
                void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z);
                Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode);
-               void computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, bool hasOffset, const Pointer<Byte> &mipmap);
-               void sampleTexel(Vector4s &c, Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, bool hasOffset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);
-               void sampleTexel(Vector4f &c, Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, bool hasOffset, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);
+               void computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, unsigned int options);
+               void sampleTexel(Vector4s &c, Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], unsigned int options);
+               void sampleTexel(Vector4f &c, Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], unsigned int options);
                void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
                Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);
 
index b986122..1aeb683 100644 (file)
@@ -1533,46 +1533,46 @@ namespace sw
 
        void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1)
        {
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, a0, a0, src0, Lod, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, a0, a0, src0, Lod, None);
        }
 
        void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1)
        {
                Float4 lod0 = Float4(0.0f);
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, a0, a0, src0, Lod, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, a0, a0, src0, Lod, None);
        }
 
        void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
        {
                Float4 lod0 = Float4(0.0f);
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, a0, a0, src2, Lod, true);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, a0, a0, src2, Lod, Offset);
        }
 
-       void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src, const Src& src1, Vector4f &offset)
+       void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
        {
-               sampleTexture(dst, src1, src.x, src.y, src.z, src.w, a0, a0, offset, Lod, true);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, a0, a0, offset, Lod, Offset);
        }
 
        void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
        {
-               UNIMPLEMENTED();
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, Float4(As<Int4>(src2.x)), src0, src0, src0, Lod, Fetch);
        }
 
        void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &offset)
        {
-               UNIMPLEMENTED();
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, Float4(As<Int4>(src2.x)), src0, src0, offset, Lod, Fetch | Offset);
        }
 
        void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
        {
                Float4 lod0 = Float4(0.0f);
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, src2, src3, src0, Grad, false);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, src2, src3, src0, Grad, None);
        }
 
        void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
        {
                Float4 lod0 = Float4(0.0f);
-               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, src2, src3, offset, Grad, true);
+               sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, src2, src3, offset, Grad, Offset);
        }
 
        void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
@@ -1581,14 +1581,14 @@ namespace sw
                sampler[src1.index]->textureSize(texture, dst, lod);
        }
 
-       void VertexProgram::sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, bool hasOffset)
+       void VertexProgram::sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, unsigned int options)
        {
                Vector4f tmp;
 
                if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID)
                {
                        Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + s.index * sizeof(Texture);
-                       sampler[s.index]->sampleTexture(texture, tmp, u, v, w, q, dsx, dsy, offset, method, hasOffset);
+                       sampler[s.index]->sampleTexture(texture, tmp, u, v, w, q, dsx, dsy, offset, options, method);
                }
                else
                {
@@ -1601,7 +1601,7 @@ namespace sw
                                        If(index == i)
                                        {
                                                Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + i * sizeof(Texture);
-                                               sampler[i]->sampleTexture(texture, tmp, u, v, w, q, dsx, dsy, offset, method, hasOffset);
+                                               sampler[i]->sampleTexture(texture, tmp, u, v, w, q, dsx, dsy, offset, options, method);
                                                // FIXME: When the sampler states are the same, we could use one sampler and just index the texture
                                        }
                                }
index 2b8c2b0..2f69178 100644 (file)
@@ -116,7 +116,7 @@ namespace sw
                void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
                void TEXSIZE(Vector4f &dst, Float4 &lod, const Src&);
 
-               void sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, bool hasOffset);
+               void sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerMethod method, unsigned int options);
 
                SamplerCore *sampler[VERTEX_TEXTURE_IMAGE_UNITS];