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;
+ case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2, project, bias); break;
case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2, project, bias); break;
case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2); break;
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2, s3); break;
}
}
- void PixelProgram::sampleTexture(Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project, SamplerMethod method)
+ 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)
{
Vector4f tmp;
if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID)
{
- sampleTexture(tmp, sampler.index, u, v, w, q, dsx, dsy, project, method);
+ sampleTexture(tmp, sampler.index, u, v, w, q, dsx, dsy, offset, project, method, hasOffset);
}
else
{
{
If(index == i)
{
- sampleTexture(tmp, i, u, v, w, q, dsx, dsy, project, method);
+ sampleTexture(tmp, i, u, v, w, q, dsx, dsy, offset, project, method, hasOffset);
// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
}
}
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, SamplerMethod method)
+ 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)
{
#if PERF_PROFILE
Long texTime = Ticks();
#endif
- Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + stage * sizeof(Texture);
+ Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture);
if(!project)
{
- sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, method);
+ sampler[samplerIndex]->sampleTexture(texture, c, u, v, w, q, dsx, dsy, offset, method, hasOffset);
}
else
{
Float4 v_q = v * rq;
Float4 w_q = w * rq;
- sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, method);
+ sampler[samplerIndex]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy, offset, method, hasOffset);
}
#if PERF_PROFILE
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, project, bias ? Bias : Implicit);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src0, project, bias ? Bias : Implicit, false);
}
- void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, bool project, bool bias)
+ void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias)
{
- UNIMPLEMENTED();
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src2, project, bias ? Bias : Implicit, true);
}
void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool project, bool bias)
{
- UNIMPLEMENTED();
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, offset, project, Lod, true);
}
void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
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, false, Grad);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, src0, false, Grad, false);
}
void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
{
- UNIMPLEMENTED();
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, offset, false, Grad, true);
}
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, project, Grad);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src2, src3, src0, project, Grad, false);
}
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, project, Lod);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, src0, src0, src0, project, Lod, false);
}
void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
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);
+ sampleTexture(texture, c, u, v, w, q, dsx, dsy, dsx, false, 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)
+ 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)
{
#if PERF_PROFILE
AddAtomic(Pointer<Long>(&profiler.texOperations), 4);
if(!hasFloatTexture())
{
- sampleFilter(texture, c, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, method);
+ sampleFilter(texture, c, uuuu, vvvv, wwww, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, method);
}
else
{
Vector4f cf;
- sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, method);
+ sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, method);
convertFixed12(c, cf);
}
}
}
- void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method)
+ 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)
{
#if PERF_PROFILE
AddAtomic(Pointer<Long>(&profiler.texOperations), 4);
computeLod3D(texture, lod, uuuu, vvvv, wwww, q.x, dsx, dsy, method);
}
- sampleFloatFilter(texture, c, uuuu, vvvv, wwww, lod, anisotropy, uDelta, vDelta, face, method);
+ sampleFloatFilter(texture, c, uuuu, vvvv, wwww, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, method);
}
else
{
Vector4s cs;
- sampleTexture(texture, cs, u, v, w, q, dsx, dsy, method, false);
+ sampleTexture(texture, cs, u, v, w, q, dsx, dsy, offset, hasOffset, method, false);
for(int component = 0; component < textureComponentCount(); component++)
{
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], SamplerMethod method)
+ 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)
{
- sampleAniso(texture, c, u, v, w, lod, anisotropy, uDelta, vDelta, face, false, method);
+ sampleAniso(texture, c, u, v, w, offset, hasOffset, 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, method);
+ sampleAniso(texture, cc, u, v, w, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, true, method);
lod *= Float(1 << 16);
}
}
- 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)
+ 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)
{
if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod)
{
- sampleQuad(texture, c, u, v, w, lod, face, secondLOD);
+ sampleQuad(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
}
else
{
Do
{
- sampleQuad(texture, c, u0, v0, w, lod, face, secondLOD);
+ sampleQuad(texture, c, u0, v0, w, offset, hasOffset, lod, face, secondLOD);
u0 += du;
v0 += dv;
}
}
- void SamplerCore::sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD)
+ 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)
{
if(state.textureType != TEXTURE_3D)
{
- sampleQuad2D(texture, c, u, v, w, lod, face, secondLOD);
+ sampleQuad2D(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
}
else
{
- sample3D(texture, c, u, v, w, lod, secondLOD);
+ sample3D(texture, c, u, v, w, offset, hasOffset, lod, secondLOD);
}
}
- void SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD)
+ 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)
{
int componentCount = textureComponentCount();
bool gather = state.textureFilter == FILTER_GATHER;
if(state.textureFilter == FILTER_POINT)
{
- sampleTexel(c, uuuu, vvvv, wwww, mipmap, buffer);
+ sampleTexel(c, uuuu, vvvv, wwww, offset, hasOffset, mipmap, buffer);
}
else
{
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, mipmap, buffer);
- sampleTexel(c1, uuuu1, vvvv0, wwww, mipmap, buffer);
- sampleTexel(c2, uuuu0, vvvv1, wwww, mipmap, buffer);
- sampleTexel(c3, uuuu1, vvvv1, wwww, mipmap, buffer);
+ 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);
if(!gather) // Blend
{
}
}
- void SamplerCore::sample3D(Pointer<Byte> &texture, Vector4s &c_, Float4 &u_, Float4 &v_, Float4 &w_, Float &lod, bool secondLOD)
+ void SamplerCore::sample3D(Pointer<Byte> &texture, Vector4s &c_, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, bool hasOffset, Float &lod, bool secondLOD)
{
int componentCount = textureComponentCount();
if(state.textureFilter == FILTER_POINT)
{
- sampleTexel(c_, uuuu, vvvv, wwww, mipmap, buffer);
+ sampleTexel(c_, uuuu, vvvv, wwww, offset, hasOffset, mipmap, buffer);
}
else
{
{
for(int k = 0; k < 2; k++)
{
- sampleTexel(c[i][j][k], u[i][j][k], v[i][j][k], s[i][j][k], mipmap, buffer);
+ sampleTexel(c[i][j][k], u[i][j][k], v[i][j][k], s[i][j][k], offset, hasOffset, mipmap, buffer);
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]); }
}
}
- 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)
+ 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)
{
- sampleFloatAniso(texture, c, u, v, w, lod, anisotropy, uDelta, vDelta, face, false, method);
+ sampleFloatAniso(texture, c, u, v, w, offset, hasOffset, 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, method);
+ sampleFloatAniso(texture, cc, u, v, w, offset, hasOffset, lod, anisotropy, uDelta, vDelta, face, true, method);
Float4 lod4 = Float4(Frac(lod));
}
}
- 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)
+ 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)
{
if(state.textureFilter != FILTER_ANISOTROPIC || method == Lod)
{
- sampleFloat(texture, c, u, v, w, lod, face, secondLOD);
+ sampleFloat(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
}
else
{
Do
{
- sampleFloat(texture, c, u0, v0, w, lod, face, secondLOD);
+ sampleFloat(texture, c, u0, v0, w, offset, hasOffset, lod, face, secondLOD);
u0 += du;
v0 += dv;
}
}
- void SamplerCore::sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD)
+ 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)
{
if(state.textureType != TEXTURE_3D)
{
- sampleFloat2D(texture, c, u, v, w, lod, face, secondLOD);
+ sampleFloat2D(texture, c, u, v, w, offset, hasOffset, lod, face, secondLOD);
}
else
{
- sampleFloat3D(texture, c, u, v, w, lod, secondLOD);
+ sampleFloat3D(texture, c, u, v, w, offset, hasOffset, lod, secondLOD);
}
}
- void SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, Int face[4], bool secondLOD)
+ 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)
{
int componentCount = textureComponentCount();
bool gather = state.textureFilter == FILTER_GATHER;
if(state.textureFilter == FILTER_POINT)
{
- sampleTexel(c, uuuu, vvvv, wwww, w, mipmap, buffer);
+ sampleTexel(c, uuuu, vvvv, wwww, offset, hasOffset, w, mipmap, buffer);
}
else
{
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, w, mipmap, buffer);
- sampleTexel(c1, uuuu1, vvvv0, wwww, w, mipmap, buffer);
- sampleTexel(c2, uuuu0, vvvv1, wwww, w, mipmap, buffer);
- sampleTexel(c3, uuuu1, vvvv1, wwww, w, mipmap, buffer);
+ 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);
if(!gather) // Blend
{
}
}
- void SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float &lod, bool secondLOD)
+ void SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, bool hasOffset, Float &lod, bool secondLOD)
{
int componentCount = textureComponentCount();
if(state.textureFilter == FILTER_POINT)
{
- sampleTexel(c, uuuu, vvvv, wwww, w, mipmap, buffer);
+ sampleTexel(c, uuuu, vvvv, wwww, offset, hasOffset, w, mipmap, buffer);
}
else
{
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, w, mipmap, buffer);
- sampleTexel(c1, uuuu1, vvvv0, wwww0, w, mipmap, buffer);
- sampleTexel(c2, uuuu0, vvvv1, wwww0, w, mipmap, buffer);
- sampleTexel(c3, uuuu1, vvvv1, wwww0, w, mipmap, buffer);
- sampleTexel(c4, uuuu0, vvvv0, wwww1, w, mipmap, buffer);
- sampleTexel(c5, uuuu1, vvvv0, wwww1, w, mipmap, buffer);
- sampleTexel(c6, uuuu0, vvvv1, wwww1, w, mipmap, buffer);
- sampleTexel(c7, uuuu1, vvvv1, wwww1, w, mipmap, buffer);
+ 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);
// Fractions
Float4 fu = Frac(Float4(As<UShort4>(uuuu0)) * *Pointer<Float4>(mipmap + OFFSET(Mipmap,fWidth)));
lodZ = z * M;
}
- void SamplerCore::computeIndices(Int index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Pointer<Byte> &mipmap)
+ Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode)
+ {
+ Int4 tmp = Int4(As<UShort4>(uvw));
+ tmp = tmp + As<Int4>(offset);
+
+ switch(mode)
+ {
+ case AddressingMode::ADDRESSING_WRAP:
+ tmp = (tmp + whd * Int4(-MIN_PROGRAM_TEXEL_OFFSET)) % whd;
+ break;
+ case AddressingMode::ADDRESSING_CLAMP:
+ 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));
+ break;
+ default:
+ ASSERT(false);
+ }
+
+ 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)
{
Short4 uuu2;
- if(!state.hasNPOTTexture && !hasFloatTexture())
+ if(!state.hasNPOTTexture && !hasFloatTexture() && !hasOffset)
{
vvvv = As<UShort4>(vvvv) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,vFrac));
uuu2 = uuuu;
{
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);
+ }
+
uuu2 = uuuu;
uuuu = As<Short4>(UnpackLow(uuuu, vvvv));
uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv));
if(state.textureType != TEXTURE_2D_ARRAY)
{
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);
+ }
}
Short4 www2 = wwww;
wwww = As<Short4>(UnpackLow(wwww, Short4(0x0000, 0x0000, 0x0000, 0x0000)));
index[3] = Extract(As<Int2>(uuu2), 1);
}
- void SamplerCore::sampleTexel(Vector4s &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4])
+ void SamplerCore::sampleTexel(Vector4s &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, bool hasOffset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4])
{
Int index[4];
- computeIndices(index, uuuu, vvvv, wwww, mipmap);
+ computeIndices(index, uuuu, vvvv, wwww, offset, hasOffset, mipmap);
int f0 = state.textureType == TEXTURE_CUBE ? 0 : 0;
int f1 = state.textureType == TEXTURE_CUBE ? 1 : 0;
c0 = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
UShort4 Y = As<UShort4>(Unpack(As<Byte4>(c0)));
- computeIndices(index, uuuu, vvvv, wwww, mipmap + sizeof(Mipmap));
+ computeIndices(index, uuuu, vvvv, wwww, offset, hasOffset, mipmap + sizeof(Mipmap));
c0 = Int(*Pointer<Byte>(buffer[1] + index[0]));
c1 = Int(*Pointer<Byte>(buffer[1] + index[1]));
c2 = Int(*Pointer<Byte>(buffer[1] + index[2]));
else ASSERT(false);
}
- void SamplerCore::sampleTexel(Vector4f &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4])
+ void SamplerCore::sampleTexel(Vector4f &c, Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, bool hasOffset, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4])
{
Int index[4];
- computeIndices(index, uuuu, vvvv, wwww, mipmap);
+ computeIndices(index, uuuu, vvvv, wwww, offset, hasOffset, mipmap);
int f0 = state.textureType == TEXTURE_CUBE ? 0 : 0;
int f1 = state.textureType == TEXTURE_CUBE ? 1 : 0;
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, 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);
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 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 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], 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], 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 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 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);
- 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]);
- void sampleTexel(Vector4f &c, Short4 &u, Short4 &v, Short4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4]);
+ 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 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);
case Shader::OPCODE_NE: notEqual(d, s0, s1); break;
case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1); break;
case Shader::OPCODE_TEX: TEX(d, s0, src1); break;
- case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2, s3); break;
+ case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2); break;
case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2); break;
case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2); break;
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2, s3); break;
void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1)
{
- sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, a0, a0, Lod);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, src0.w, a0, a0, src0, Lod, false);
}
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, Lod);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, a0, a0, src0, Lod, false);
}
- void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
+ void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
{
- UNIMPLEMENTED();
+ Float4 lod0 = Float4(0.0f);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, a0, a0, src2, Lod, true);
}
- void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset)
+ void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src, const Src& src1, Vector4f &offset)
{
- UNIMPLEMENTED();
+ sampleTexture(dst, src1, src.x, src.y, src.z, src.w, a0, a0, offset, Lod, true);
}
void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
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, Grad);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, src2, src3, src0, Grad, false);
}
void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
{
- UNIMPLEMENTED();
+ Float4 lod0 = Float4(0.0f);
+ sampleTexture(dst, src1, src0.x, src0.y, src0.z, lod0, src2, src3, offset, Grad, true);
}
void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
}
}
- void VertexProgram::sampleTexture(Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, SamplerMethod method)
+ 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)
{
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, method);
+ sampler[s.index]->sampleTexture(texture, tmp, u, v, w, q, dsx, dsy, offset, method, hasOffset);
}
else
{
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, method);
+ sampler[i]->sampleTexture(texture, tmp, u, v, w, q, dsx, dsy, offset, method, hasOffset);
// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
}
}