Refactor sampler LOD calculation method into an enum. Change-Id: I0beed96cd68608ce07aec0b11f14d6f61e67e53d Reviewed-on: https://swiftshader-review.googlesource.com/5034 Tested-by: Nicolas Capens <capn@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Shader/PixelPipeline.cpp b/src/Shader/PixelPipeline.cpp index 7669163..99f91e7 100644 --- a/src/Shader/PixelPipeline.cpp +++ b/src/Shader/PixelPipeline.cpp
@@ -94,9 +94,9 @@ Vector4s s1; Vector4s s2; - if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegisterS(src0); - if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegisterS(src1); - if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegisterS(src2); + if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0); + if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1); + if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2); Float4 x = version < 0x0104 ? v[2 + dst.index].x : v[2 + src0.index].x; Float4 y = version < 0x0104 ? v[2 + dst.index].y : v[2 + src0.index].y; @@ -1221,25 +1221,20 @@ sampleTexture(c, stage, x, y, z, w, project); } - void PixelPipeline::sampleTexture(Vector4s &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project, bool bias) + void PixelPipeline::sampleTexture(Vector4s &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project) { + #if PERF_PROFILE + Long texTime = Ticks(); + #endif + Vector4f dsx; Vector4f dsy; - sampleTexture(c, stage, u, v, w, q, dsx, dsy, project, bias, false); - } - - void PixelPipeline::sampleTexture(Vector4s &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, bool bias, bool gradients, bool lodProvided) - { -#if PERF_PROFILE - Long texTime = Ticks(); -#endif - Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + stage * sizeof(Texture); if(!project) { - sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, bias, gradients, lodProvided); + sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy); } else { @@ -1249,12 +1244,12 @@ Float4 v_q = v * rq; Float4 w_q = w * rq; - sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, bias, gradients, lodProvided); + sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy); } -#if PERF_PROFILE - cycles[PERF_TEX] += Ticks() - texTime; -#endif + #if PERF_PROFILE + cycles[PERF_TEX] += Ticks() - texTime; + #endif } Short4 PixelPipeline::convertFixed12(RValue<Float4> cf) @@ -1317,7 +1312,7 @@ } } - Vector4s PixelPipeline::fetchRegisterS(const Src &src) + Vector4s PixelPipeline::fetchRegister(const Src &src) { Vector4s *reg; int i = src.index;
diff --git a/src/Shader/PixelPipeline.hpp b/src/Shader/PixelPipeline.hpp index fd76b3e..4d0362d 100644 --- a/src/Shader/PixelPipeline.hpp +++ b/src/Shader/PixelPipeline.hpp
@@ -57,8 +57,7 @@ void specularPixel(Vector4s ¤t, Vector4s &specular); void sampleTexture(Vector4s &c, int coordinates, int sampler, bool project = false); - void sampleTexture(Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false, bool bias = false); - void sampleTexture(Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false); + void sampleTexture(Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false); Short4 convertFixed12(RValue<Float4> cf); void convertFixed12(Vector4s &cs, Vector4f &cf); @@ -66,7 +65,7 @@ void convertSigned12(Vector4f &cf, Vector4s &cs); void writeDestination(Vector4s &d, const Dst &dst); - Vector4s fetchRegisterS(const Src &src); + Vector4s fetchRegister(const Src &src); // Instructions void MOV(Vector4s &dst, Vector4s &src0);
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp index 0286bc30..6eca4eb 100644 --- a/src/Shader/PixelProgram.cpp +++ b/src/Shader/PixelProgram.cpp
@@ -136,11 +136,11 @@ } } - if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegisterF(src0); - if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegisterF(src1); - if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegisterF(src2); - if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegisterF(src3); - if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegisterF(src4); + if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0); + if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1); + if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2); + if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegister(src3); + if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegister(src4); switch(opcode) { @@ -270,8 +270,8 @@ case Shader::OPCODE_M3X3: M3X3(d, s0, src1); break; case Shader::OPCODE_M3X2: M3X2(d, s0, src1); break; case Shader::OPCODE_TEX: TEXLD(d, s0, src1, project, bias); break; - case Shader::OPCODE_TEXLDD: TEXLDD(d, s0, src1, s2, s3, project, bias); break; - case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1, project, bias); break; + case Shader::OPCODE_TEXLDD: TEXLDD(d, s0, src1, s2, s3, project); break; + case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1, project); break; case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break; case Shader::OPCODE_TEXKILL: TEXKILL(cMask, d, dst.mask); break; case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2, s3, project, bias); break; @@ -624,15 +624,17 @@ } } - void PixelProgram::sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, bool bias, bool gradients, bool lodProvided) + void PixelProgram::sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method) { + Vector4f tmp; + if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID) { - sampleTexture(c, sampler.index, u, v, w, q, dsx, dsy, project, bias, gradients, lodProvided); + sampleTexture(tmp, sampler.index, u, v, w, q, dsx, dsy, project, method); } else { - Int index = As<Int>(Float(fetchRegisterF(sampler).x.x)); + Int index = As<Int>(Float(fetchRegister(sampler).x.x)); for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++) { @@ -640,25 +642,30 @@ { If(index == i) { - sampleTexture(c, i, u, v, w, q, dsx, dsy, project, bias, gradients, lodProvided); + sampleTexture(tmp, i, u, v, w, q, dsx, dsy, project, method); // FIXME: When the sampler states are the same, we could use one sampler and just index the texture } } } } + + c.x = tmp[(sampler.swizzle >> 0) & 0x3]; + c.y = tmp[(sampler.swizzle >> 2) & 0x3]; + c.z = tmp[(sampler.swizzle >> 4) & 0x3]; + c.w = tmp[(sampler.swizzle >> 6) & 0x3]; } - void PixelProgram::sampleTexture(Vector4f &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, bool bias, bool gradients, bool lodProvided) + void PixelProgram::sampleTexture(Vector4f &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method) { -#if PERF_PROFILE - Long texTime = Ticks(); -#endif + #if PERF_PROFILE + Long texTime = Ticks(); + #endif Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + stage * sizeof(Texture); if(!project) { - sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, bias, gradients, lodProvided); + sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, method); } else { @@ -668,12 +675,12 @@ Float4 v_q = v * rq; Float4 w_q = w * rq; - sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, bias, gradients, lodProvided); + sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, method); } -#if PERF_PROFILE - cycles[PERF_TEX] += Ticks() - texTime; -#endif + #if PERF_PROFILE + cycles[PERF_TEX] += Ticks() - texTime; + #endif } void PixelProgram::clampColor(Vector4f oC[RENDERTARGETS]) @@ -743,7 +750,7 @@ return enable; } - Vector4f PixelProgram::fetchRegisterF(const Src &src, unsigned int offset) + Vector4f PixelProgram::fetchRegister(const Src &src, unsigned int offset) { Vector4f reg; unsigned int i = src.index + offset; @@ -989,8 +996,8 @@ void PixelProgram::M3X2(Vector4f &dst, Vector4f &src0, const Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); dst.x = dot3(src0, row0); dst.y = dot3(src0, row1); @@ -998,9 +1005,9 @@ void PixelProgram::M3X3(Vector4f &dst, Vector4f &src0, const Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); dst.x = dot3(src0, row0); dst.y = dot3(src0, row1); @@ -1009,10 +1016,10 @@ void PixelProgram::M3X4(Vector4f &dst, Vector4f &src0, const Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); - Vector4f row3 = fetchRegisterF(src1, 3); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); + Vector4f row3 = fetchRegister(src1, 3); dst.x = dot3(src0, row0); dst.y = dot3(src0, row1); @@ -1022,9 +1029,9 @@ void PixelProgram::M4X3(Vector4f &dst, Vector4f &src0, const Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); dst.x = dot4(src0, row0); dst.y = dot4(src0, row1); @@ -1033,10 +1040,10 @@ void PixelProgram::M4X4(Vector4f &dst, Vector4f &src0, const Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); - Vector4f row3 = fetchRegisterF(src1, 3); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); + Vector4f row3 = fetchRegister(src1, 3); dst.x = dot4(src0, row0); dst.y = dot4(src0, row1); @@ -1046,13 +1053,7 @@ void PixelProgram::TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias) { - Vector4f tmp; - sampleTexture(tmp, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, project, bias); - - dst.x = tmp[(src1.swizzle >> 0) & 0x3]; - dst.y = tmp[(src1.swizzle >> 2) & 0x3]; - dst.z = tmp[(src1.swizzle >> 4) & 0x3]; - dst.w = tmp[(src1.swizzle >> 6) & 0x3]; + sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, project, bias ? Bias : Implicit); } void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, bool project, bool bias) @@ -1085,26 +1086,14 @@ UNIMPLEMENTED(); } - void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project, bool bias) + void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project) { - Vector4f tmp; - sampleTexture(tmp, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, project, bias, true); - - dst.x = tmp[(src1.swizzle >> 0) & 0x3]; - dst.y = tmp[(src1.swizzle >> 2) & 0x3]; - dst.z = tmp[(src1.swizzle >> 4) & 0x3]; - dst.w = tmp[(src1.swizzle >> 6) & 0x3]; + sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, project, Grad); } - void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias) + void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project) { - Vector4f tmp; - sampleTexture(tmp, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, project, bias, false, true); - - dst.x = tmp[(src1.swizzle >> 0) & 0x3]; - dst.y = tmp[(src1.swizzle >> 2) & 0x3]; - dst.z = tmp[(src1.swizzle >> 4) & 0x3]; - dst.w = tmp[(src1.swizzle >> 6) & 0x3]; + sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, project, Lod); } void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1) @@ -1458,7 +1447,7 @@ } else { - Int4 condition = As<Int4>(fetchRegisterF(src).x); + Int4 condition = As<Int4>(fetchRegister(src).x); IF(condition); } } @@ -1627,7 +1616,7 @@ Nucleus::setInsertBlock(testBlock); enableContinue = restoreContinue; - const Vector4f &src = fetchRegisterF(temporaryRegister); + const Vector4f &src = fetchRegister(temporaryRegister); Int4 condition = As<Int4>(src.x); condition &= enableStack[enableIndex - 1]; enableStack[enableIndex] = condition;
diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp index ab69b62..085255d 100644 --- a/src/Shader/PixelProgram.hpp +++ b/src/Shader/PixelProgram.hpp
@@ -13,6 +13,7 @@ #define sw_PixelProgram_hpp #include "PixelRoutine.hpp" +#include "SamplerCore.hpp" namespace sw { @@ -78,15 +79,15 @@ Int4 enableContinue; Int4 enableLeave; - void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false); - void sampleTexture(Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false); + void sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method); + void sampleTexture(Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method); // Raster operations void clampColor(Vector4f oC[RENDERTARGETS]); Int4 enableMask(const Shader::Instruction *instruction); - Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0); + Vector4f fetchRegister(const Src &src, unsigned int offset = 0); Vector4f readConstant(const Src &src, unsigned int offset = 0); RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index); RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset); @@ -103,8 +104,8 @@ void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1); void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1); void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias); - void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project, bool bias); - void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias); + void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project); + void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, bool project); void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1); void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask); void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, bool project, bool bias);
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp index 82a6644..8128617 100644 --- a/src/Shader/SamplerCore.cpp +++ b/src/Shader/SamplerCore.cpp
@@ -51,7 +51,12 @@ { } - void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided, bool fixed12) + void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method) + { + sampleTexture(texture, c, u, v, w, q, dsx, dsy, method, true); + } + + void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method, bool fixed12) { #if PERF_PROFILE AddAtomic(Pointer<Long>(&profiler.texOperations), 4); @@ -101,16 +106,16 @@ { if(state.textureType != TEXTURE_CUBE) { - computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, q.x, dsx, dsy, bias, gradients, lodProvided); + computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, q.x, dsx, dsy, method); } else { - computeLod(texture, lod, anisotropy, uDelta, vDelta, lodU, lodV, q.x, dsx, dsy, bias, gradients, lodProvided); + computeLod(texture, lod, anisotropy, uDelta, vDelta, lodU, lodV, q.x, dsx, dsy, method); } } else { - computeLod3D(texture, lod, uuuu, vvvv, wwww, q.x, dsx, dsy, bias, gradients, lodProvided); + computeLod3D(texture, lod, uuuu, vvvv, wwww, q.x, dsx, dsy, method); } if(state.textureType == TEXTURE_CUBE) @@ -121,13 +126,13 @@ if(!hasFloatTexture()) { - sampleFilter(texture, c, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, lodProvided); + sampleFilter(texture, c, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, method); } else { Vector4f cf; - sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, lodProvided); + sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, method); convertFixed12(c, cf); } @@ -287,7 +292,7 @@ } } - void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided) + void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method) { #if PERF_PROFILE AddAtomic(Pointer<Long>(&profiler.texOperations), 4); @@ -331,16 +336,16 @@ { if(state.textureType != TEXTURE_CUBE) { - computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, q.x, dsx, dsy, bias, gradients, lodProvided); + computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, q.x, dsx, dsy, method); } else { - computeLod(texture, lod, anisotropy, uDelta, vDelta, lodU, lodV, q.x, dsx, dsy, bias, gradients, lodProvided); + computeLod(texture, lod, anisotropy, uDelta, vDelta, lodU, lodV, q.x, dsx, dsy, method); } } else { - computeLod3D(texture, lod, uuuu, vvvv, wwww, q.x, dsx, dsy, bias, gradients, lodProvided); + computeLod3D(texture, lod, uuuu, vvvv, wwww, q.x, dsx, dsy, method); } if(state.textureType == TEXTURE_CUBE) @@ -349,13 +354,13 @@ vvvv += Float4(0.5f); } - sampleFloatFilter(texture, c, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, lodProvided); + sampleFloatFilter(texture, c, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, method); } else { Vector4s cs; - sampleTexture(texture, cs, u, v, w, q, dsx, dsy, bias, gradients, lodProvided, false); + sampleTexture(texture, cs, u, v, w, q, dsx, dsy, method, false); for(int component = 0; component < textureComponentCount(); component++) { @@ -593,15 +598,15 @@ return uvw; } - void SamplerCore::sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool lodProvided) + void SamplerCore::sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method) { - sampleAniso(texture, c, u, v, w, lod, anisotropy, uDelta, vDelta, face, false, lodProvided); + sampleAniso(texture, c, u, v, w, lod, anisotropy, uDelta, vDelta, face, false, method); if(state.mipmapFilter > MIPMAP_POINT) { Vector4s cc; - sampleAniso(texture, cc, u, v, w, lod, anisotropy, uDelta, vDelta, face, true, lodProvided); + sampleAniso(texture, cc, u, v, w, lod, anisotropy, uDelta, vDelta, face, true, method); lod *= Float(1 << 16); @@ -689,9 +694,9 @@ } } - void SamplerCore::sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, bool lodProvided) + void SamplerCore::sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method) { - if(state.textureFilter != FILTER_ANISOTROPIC || lodProvided) + if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod) { sampleQuad(texture, c, u, v, w, lod, face, secondLOD); } @@ -1093,15 +1098,15 @@ } } - void SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool lodProvided) + void SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerMethod method) { - sampleFloatAniso(texture, c, u, v, w, lod, anisotropy, uDelta, vDelta, face, false, lodProvided); + sampleFloatAniso(texture, c, u, v, w, lod, anisotropy, uDelta, vDelta, face, false, method); if(state.mipmapFilter > MIPMAP_POINT) { Vector4f cc; - sampleFloatAniso(texture, cc, u, v, w, lod, anisotropy, uDelta, vDelta, face, true, lodProvided); + sampleFloatAniso(texture, cc, u, v, w, lod, anisotropy, uDelta, vDelta, face, true, method); Float4 lod4 = Float4(Frac(lod)); @@ -1168,9 +1173,9 @@ } } - void SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, bool lodProvided) + void SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerMethod method) { - if(state.textureFilter != FILTER_ANISOTROPIC || lodProvided) + if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod) { sampleFloat(texture, c, u, v, w, lod, face, secondLOD); } @@ -1390,13 +1395,13 @@ } } - void SamplerCore::computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &uuuu, Float4 &vvvv, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided) + void SamplerCore::computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &uuuu, Float4 &vvvv, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method) { - if(!lodProvided) + if(method != Lod) { Float4 duvdxy; - if(!gradients) + if(method != Grad) { duvdxy = Float4(uuuu.yz, vvvv.yz) - Float4(uuuu.xx, vvvv.xx); } @@ -1440,7 +1445,7 @@ lod -= Float(0x3F800000); lod *= As<Float>(Int(0x33800000)); - if(bias) + if(method == Bias) { lod += lodBias; } @@ -1460,20 +1465,20 @@ lod = Min(lod, Float(MIPMAP_LEVELS - 2)); // Trilinear accesses lod+1 } - void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided) + void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerMethod method) { if(state.mipmapFilter == MIPMAP_NONE) { } else // Point and linear filter { - if(!lodProvided) + if(method != Lod) { Float4 dudxy; Float4 dvdxy; Float4 dsdxy; - if(!gradients) + if(method != Grad) { dudxy = uuuu.ywyw - uuuu; dvdxy = vvvv.ywyw - vvvv; @@ -1513,7 +1518,7 @@ lod -= Float(0x3F800000); lod *= As<Float>(Int(0x33800000)); - if(bias) + if(method == Bias) { lod += lodBias; }
diff --git a/src/Shader/SamplerCore.hpp b/src/Shader/SamplerCore.hpp index 75d8f31..bb8324f 100644 --- a/src/Shader/SamplerCore.hpp +++ b/src/Shader/SamplerCore.hpp
@@ -17,30 +17,40 @@ namespace sw { + enum SamplerMethod + { + Implicit, + Bias, + Lod, + Grad, + }; + class SamplerCore { 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, bool bias = false, bool gradients = false, bool lodProvided = false, bool fixed12 = true); - void sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool bias = false, bool gradients = false, bool lodProvided = false); + 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, SamplerMethod method = Implicit); private: + void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, 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, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool lodProvided); - void sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, bool lodProvided); + void sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, 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, 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, Float &lod, Int face[4], bool secondLOD); void sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD); void sample3D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD); - void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool lodProvided); - void sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, bool lodProvided); + void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, 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, 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, Float &lod, Int face[4], bool secondLOD); void sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD); void sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD); - void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided); - void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided); + 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 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 &lodU, Float4 &lodV, Float4 &x, Float4 &y, Float4 &z); void computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Pointer<Byte> &mipmap); void sampleTexel(Vector4s &c, Short4 &u, Short4 &v, Short4 &s, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);
diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp index dc829ef..e0ecd73 100644 --- a/src/Shader/VertexProgram.cpp +++ b/src/Shader/VertexProgram.cpp
@@ -136,11 +136,11 @@ Vector4f s3; Vector4f s4; - if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegisterF(src0); - if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegisterF(src1); - if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegisterF(src2); - if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegisterF(src3); - if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegisterF(src4); + if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegister(src0); + if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1); + if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2); + if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegister(src3); + if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegister(src4); switch(opcode) { @@ -647,7 +647,7 @@ } } - Vector4f VertexProgram::fetchRegisterF(const Src &src, unsigned int offset) + Vector4f VertexProgram::fetchRegister(const Src &src, unsigned int offset) { Vector4f reg; unsigned int i = src.index + offset; @@ -830,7 +830,7 @@ if(src.rel.deterministic) { Int a = relativeAddress(src, src.bufferIndex); - + c.x = c.y = c.z = c.w = *Pointer<Float4>(uniformAddress(src.bufferIndex, i, a)); c.x = c.x.xxxx; @@ -930,8 +930,8 @@ void VertexProgram::M3X2(Vector4f &dst, Vector4f &src0, Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); dst.x = dot3(src0, row0); dst.y = dot3(src0, row1); @@ -939,9 +939,9 @@ void VertexProgram::M3X3(Vector4f &dst, Vector4f &src0, Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); dst.x = dot3(src0, row0); dst.y = dot3(src0, row1); @@ -950,10 +950,10 @@ void VertexProgram::M3X4(Vector4f &dst, Vector4f &src0, Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); - Vector4f row3 = fetchRegisterF(src1, 3); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); + Vector4f row3 = fetchRegister(src1, 3); dst.x = dot3(src0, row0); dst.y = dot3(src0, row1); @@ -963,9 +963,9 @@ void VertexProgram::M4X3(Vector4f &dst, Vector4f &src0, Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); dst.x = dot4(src0, row0); dst.y = dot4(src0, row1); @@ -974,10 +974,10 @@ void VertexProgram::M4X4(Vector4f &dst, Vector4f &src0, Src &src1) { - Vector4f row0 = fetchRegisterF(src1, 0); - Vector4f row1 = fetchRegisterF(src1, 1); - Vector4f row2 = fetchRegisterF(src1, 2); - Vector4f row3 = fetchRegisterF(src1, 3); + Vector4f row0 = fetchRegister(src1, 0); + Vector4f row1 = fetchRegister(src1, 1); + Vector4f row2 = fetchRegister(src1, 2); + Vector4f row3 = fetchRegister(src1, 3); dst.x = dot4(src0, row0); dst.y = dot4(src0, row1); @@ -1259,7 +1259,7 @@ } else { - Int4 condition = As<Int4>(fetchRegisterF(src).x); + Int4 condition = As<Int4>(fetchRegister(src).x); IF(condition); } } @@ -1429,7 +1429,7 @@ Nucleus::setInsertBlock(testBlock); enableContinue = restoreContinue; - const Vector4f &src = fetchRegisterF(temporaryRegister); + const Vector4f &src = fetchRegister(temporaryRegister); Int4 condition = As<Int4>(src.x); condition &= enableStack[enableIndex - 1]; enableStack[enableIndex] = condition; @@ -1494,25 +1494,13 @@ void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1) { - Vector4f tmp; - sampleTexture(tmp, src1, src0.x, src0.y, src0.z, src0.w); - - dst.x = tmp[(src1.swizzle >> 0) & 0x3]; - dst.y = tmp[(src1.swizzle >> 2) & 0x3]; - dst.z = tmp[(src1.swizzle >> 4) & 0x3]; - dst.w = tmp[(src1.swizzle >> 6) & 0x3]; + sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, Lod); } void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1) { - Float4 lod = Float4(0.0f); - Vector4f tmp; - sampleTexture(tmp, src1, src0.x, src0.y, src0.z, lod); - - dst.x = tmp[(src1.swizzle >> 0) & 0x3]; - dst.y = tmp[(src1.swizzle >> 2) & 0x3]; - dst.z = tmp[(src1.swizzle >> 4) & 0x3]; - dst.w = tmp[(src1.swizzle >> 6) & 0x3]; + Float4 lod0 = Float4(0.0f); + sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, Lod); } void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3) @@ -1557,29 +1545,36 @@ } } - void VertexProgram::sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q) + void VertexProgram::sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, SamplerMethod method) { + Vector4f tmp; + if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID) { - Pointer<Byte> texture = data + OFFSET(DrawData,mipmap[16]) + s.index * sizeof(Texture); - sampler[s.index]->sampleTexture(texture, c, u, v, w, q, a0, a0, false, false, true); + Pointer<Byte> texture = data + OFFSET(DrawData,mipmap[TEXTURE_IMAGE_UNITS]) + s.index * sizeof(Texture); + sampler[s.index]->sampleTexture(texture, tmp, u, v, w, q, a0, a0, method); } else { - Int index = As<Int>(Float(fetchRegisterF(s).x.x)); + Int index = As<Int>(Float(fetchRegister(s).x.x)); - for(int i = 0; i < 16; i++) + for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++) { if(shader->usesSampler(i)) { If(index == i) { - Pointer<Byte> texture = data + OFFSET(DrawData,mipmap[16]) + i * sizeof(Texture); - sampler[i]->sampleTexture(texture, c, u, v, w, q, a0, a0, false, false, true); + Pointer<Byte> texture = data + OFFSET(DrawData,mipmap[TEXTURE_IMAGE_UNITS]) + i * sizeof(Texture); + sampler[i]->sampleTexture(texture, tmp, u, v, w, q, a0, a0, method); // FIXME: When the sampler states are the same, we could use one sampler and just index the texture } } } } + + c.x = tmp[(s.swizzle >> 0) & 0x3]; + c.y = tmp[(s.swizzle >> 2) & 0x3]; + c.z = tmp[(s.swizzle >> 4) & 0x3]; + c.w = tmp[(s.swizzle >> 6) & 0x3]; } }
diff --git a/src/Shader/VertexProgram.hpp b/src/Shader/VertexProgram.hpp index 1819d91..98e09cd 100644 --- a/src/Shader/VertexProgram.hpp +++ b/src/Shader/VertexProgram.hpp
@@ -14,6 +14,7 @@ #include "VertexRoutine.hpp" #include "ShaderCore.hpp" +#include "SamplerCore.hpp" #include "Stream.hpp" #include "Types.hpp" @@ -22,7 +23,6 @@ { struct Stream; class VertexShader; - class SamplerCore; class VertexProgram : public VertexRoutine, public ShaderCore { @@ -63,7 +63,7 @@ void program(); void passThrough(); - Vector4f fetchRegisterF(const Src &src, unsigned int offset = 0); + Vector4f fetchRegister(const Src &src, unsigned int offset = 0); Vector4f readConstant(const Src &src, unsigned int offset = 0); RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index); RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset); @@ -111,7 +111,7 @@ 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); + void sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, SamplerMethod method); SamplerCore *sampler[VERTEX_TEXTURE_IMAGE_UNITS];