Commit 467ce5a1 by Nicolas Capens Committed by Nicolas Capens

Implement mipmap base/max level.

Change-Id: I611815fb0dcbba97e67f3c146dffb463f133447e Reviewed-on: https://swiftshader-review.googlesource.com/15248Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent b3f54e84
......@@ -3172,7 +3172,7 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
}
else UNREACHABLE(type);
sw::Resource *resource = 0;
sw::Resource *resource = nullptr;
if(baseTexture && textureUsed)
{
......@@ -3183,7 +3183,8 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
if(baseTexture && textureUsed)
{
int topLevel = baseTexture->getTopLevel();
int baseLevel = baseTexture->getBaseLevel();
int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
{
......@@ -3193,13 +3194,13 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
{
int surfaceLevel = mipmapLevel;
if(surfaceLevel < 0)
if(surfaceLevel < baseLevel)
{
surfaceLevel = 0;
surfaceLevel = baseLevel;
}
else if(surfaceLevel > topLevel)
else if(surfaceLevel > maxLevel)
{
surfaceLevel = topLevel;
surfaceLevel = maxLevel;
}
egl::Image *surface = texture->getImage(surfaceLevel);
......@@ -3214,13 +3215,13 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
{
int surfaceLevel = mipmapLevel;
if(surfaceLevel < 0)
if(surfaceLevel < baseLevel)
{
surfaceLevel = 0;
surfaceLevel = baseLevel;
}
else if(surfaceLevel > topLevel)
else if(surfaceLevel > maxLevel)
{
surfaceLevel = topLevel;
surfaceLevel = maxLevel;
}
egl::Image *surface = texture->getImage(surfaceLevel);
......@@ -3235,13 +3236,13 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
{
int surfaceLevel = mipmapLevel;
if(surfaceLevel < 0)
if(surfaceLevel < baseLevel)
{
surfaceLevel = 0;
surfaceLevel = baseLevel;
}
else if(surfaceLevel > topLevel)
else if(surfaceLevel > maxLevel)
{
surfaceLevel = topLevel;
surfaceLevel = maxLevel;
}
egl::Image *surface = texture->getImage(surfaceLevel);
......@@ -3260,13 +3261,13 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
{
int surfaceLevel = mipmapLevel;
if(surfaceLevel < 0)
if(surfaceLevel < baseLevel)
{
surfaceLevel = 0;
surfaceLevel = baseLevel;
}
else if(surfaceLevel > topLevel)
else if(surfaceLevel > maxLevel)
{
surfaceLevel = topLevel;
surfaceLevel = maxLevel;
}
egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
......
......@@ -182,6 +182,11 @@ bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
bool Texture::setBaseLevel(GLint baseLevel)
{
if(baseLevel < 0)
{
return false;
}
mBaseLevel = baseLevel;
return true;
}
......@@ -844,12 +849,14 @@ bool Texture2D::isMipmapComplete() const
return false;
}
if(image[level]->getWidth() != std::max(1, width >> level))
int i = level - mBaseLevel;
if(image[level]->getWidth() != std::max(1, width >> i))
{
return false;
}
if(image[level]->getHeight() != std::max(1, height >> level))
if(image[level]->getHeight() != std::max(1, height >> i))
{
return false;
}
......@@ -1213,7 +1220,9 @@ bool TextureCubeMap::isMipmapCubeComplete() const
return false;
}
if(image[face][level]->getWidth() != std::max(1, size >> level))
int i = level - mBaseLevel;
if(image[face][level]->getWidth() != std::max(1, size >> i))
{
return false;
}
......@@ -1833,17 +1842,19 @@ bool Texture3D::isMipmapComplete() const
return false;
}
if(image[level]->getWidth() != std::max(1, width >> level))
int i = level - mBaseLevel;
if(image[level]->getWidth() != std::max(1, width >> i))
{
return false;
}
if(image[level]->getHeight() != std::max(1, height >> level))
if(image[level]->getHeight() != std::max(1, height >> i))
{
return false;
}
int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> level);
int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> i);
if(image[level]->getDepth() != levelDepth)
{
return false;
......
......@@ -525,17 +525,17 @@ namespace sw
mask = As<Int4>(CmpLT(Abs(coordinates - Float4(0.5f)), Float4(0.5f)));
}
Short4 SamplerCore::offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod)
Short4 SamplerCore::offsetSample(Pointer<Byte> &texture, Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod)
{
Short4 offset = *Pointer<Short4>(mipmap + halfOffset);
if(state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
{
offset &= Short4(CmpNLE(Float4(lod), Float4(0.0f)));
offset &= Short4(CmpNLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel))))));
}
else if(state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR)
{
offset &= Short4(CmpLE(Float4(lod), Float4(0.0f)));
offset &= Short4(CmpLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel))))));
}
if(wrap)
......@@ -759,10 +759,10 @@ namespace sw
}
else
{
Short4 uuuu0 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 0 : -1, lod);
Short4 vvvv0 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 0 : -1, lod);
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);
Short4 uuuu0 = offsetSample(texture, uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 0 : -1, lod);
Short4 vvvv0 = offsetSample(texture, vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 0 : -1, lod);
Short4 uuuu1 = offsetSample(texture, uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, gather ? 2 : +1, lod);
Short4 vvvv1 = offsetSample(texture, vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, gather ? 2 : +1, lod);
Vector4s c0 = sampleTexel(uuuu0, vvvv0, wwww, offset, mipmap, buffer, function);
Vector4s c1 = sampleTexel(uuuu1, vvvv0, wwww, offset, mipmap, buffer, function);
......@@ -966,9 +966,9 @@ namespace sw
{
for(int k = 0; k < 2; k++)
{
u[i][j][k] = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, i * 2 - 1, lod);
v[i][j][k] = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, j * 2 - 1, lod);
s[i][j][k] = offsetSample(wwww, mipmap, OFFSET(Mipmap,wHalf), state.addressingModeW == ADDRESSING_WRAP, k * 2 - 1, lod);
u[i][j][k] = offsetSample(texture, uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, i * 2 - 1, lod);
v[i][j][k] = offsetSample(texture, vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, j * 2 - 1, lod);
s[i][j][k] = offsetSample(texture, wwww, mipmap, OFFSET(Mipmap,wHalf), state.addressingModeW == ADDRESSING_WRAP, k * 2 - 1, lod);
}
}
}
......@@ -1219,7 +1219,7 @@ namespace sw
Int4 x0, x1, y0, y1, z0;
Float4 fu, fv;
Int4 filter = computeFilterOffset(lod);
Int4 filter = computeFilterOffset(texture, lod);
address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU, function);
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(w, z0, z0, fv, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
......@@ -1288,7 +1288,7 @@ namespace sw
Int4 x0, x1, y0, y1, z0, z1;
Float4 fu, fv, fw;
Int4 filter = computeFilterOffset(lod);
Int4 filter = computeFilterOffset(texture, lod);
address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU, function);
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(w, z0, z1, fw, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
......@@ -1431,19 +1431,22 @@ namespace sw
}
else if(function == Lod)
{
lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = lodBias;
}
else if(function == Fetch)
{
// TODO: Eliminate int-float-int conversion.
lod = Float(As<Int>(lodBias)) + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Float(As<Int>(lodBias));
}
else if(function == Base)
{
lod = Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Float(0);
}
else assert(false);
// TODO: Avoid float conversion.
lod += Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
......@@ -1497,19 +1500,22 @@ namespace sw
}
else if(function == Lod)
{
lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = lodBias;
}
else if(function == Fetch)
{
// TODO: Eliminate int-float-int conversion.
lod = Float(As<Int>(lodBias)) + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Float(As<Int>(lodBias));
}
else if(function == Base)
{
lod = Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Float(0);
}
else assert(false);
// TODO: Avoid float conversion.
lod += Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
......@@ -1561,19 +1567,22 @@ namespace sw
}
else if(function == Lod)
{
lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = lodBias;
}
else if(function == Fetch)
{
// TODO: Eliminate int-float-int conversion.
lod = Float(As<Int>(lodBias)) + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Float(As<Int>(lodBias));
}
else if(function == Base)
{
lod = Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Float(0);
}
else assert(false);
// TODO: Avoid float conversion.
lod += Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
......@@ -2277,7 +2286,7 @@ namespace sw
}
}
Int4 SamplerCore::computeFilterOffset(Float &lod)
Int4 SamplerCore::computeFilterOffset(Pointer<Byte> &texture, Float &lod)
{
Int4 filter = -1;
......@@ -2287,11 +2296,11 @@ namespace sw
}
else if(state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
{
filter = CmpNLE(Float4(lod), Float4(0.0f));
filter = CmpNLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)))));
}
else if(state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR)
{
filter = CmpLE(Float4(lod), Float4(0.0f));
filter = CmpLE(Float4(lod), Float4(Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)))));
}
return filter;
......
......@@ -59,7 +59,7 @@ namespace sw
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);
Short4 offsetSample(Pointer<Byte> &texture, Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
......@@ -85,7 +85,7 @@ namespace sw
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);
void address(Float4 &uw, Int4& xyz0, Int4& xyz1, Float4& f, Pointer<Byte>& mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function);
Int4 computeFilterOffset(Float &lod);
Int4 computeFilterOffset(Pointer<Byte> &texture, Float &lod);
void convertFixed12(Short4 &ci, Float4 &cf);
void convertFixed12(Vector4s &cs, Vector4f &cf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment