Commit f15e8940 by Alexis Hetu Committed by Alexis Hétu

Enabled 2D array textures

- Implemented mipmap generation and completeness checks for Texture2DArray. - Fixed texture parameters setters and getters along with mipmap generation functions to use the proper 2D array texture instead of the 3D texture for 2D array textures. - Enabled the same path as 3D texture for 2D array textures in the sampler. - Added an address function for the w component, which simply clamps the rounded value for 2D array textures and adapted SamplerCore::computeIndices to this new behavior. Change-Id: Ida0659afac75330bfd9af4052cfd2625c729f9ef Reviewed-on: https://swiftshader-review.googlesource.com/4310Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 9c025c0a
...@@ -1725,8 +1725,10 @@ bool Texture3D::isMipmapComplete() const ...@@ -1725,8 +1725,10 @@ bool Texture3D::isMipmapComplete() const
GLsizei width = image[mBaseLevel]->getWidth(); GLsizei width = image[mBaseLevel]->getWidth();
GLsizei height = image[mBaseLevel]->getHeight(); GLsizei height = image[mBaseLevel]->getHeight();
GLsizei depth = image[mBaseLevel]->getDepth(); GLsizei depth = image[mBaseLevel]->getDepth();
bool isTexture2DArray = getTarget() == GL_TEXTURE_2D_ARRAY;
int q = std::min(log2(std::max(std::max(width, height), depth)), mMaxLevel); int q = isTexture2DArray ? std::min(log2(std::max(width, height)), mMaxLevel) :
std::min(log2(std::max(std::max(width, height), depth)), mMaxLevel);
for(int level = mBaseLevel + 1; level <= q; level++) for(int level = mBaseLevel + 1; level <= q; level++)
{ {
...@@ -1755,7 +1757,8 @@ bool Texture3D::isMipmapComplete() const ...@@ -1755,7 +1757,8 @@ bool Texture3D::isMipmapComplete() const
return false; return false;
} }
if(image[level]->getDepth() != std::max(1, depth >> level)) int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> level);
if(image[level]->getDepth() != levelDepth)
{ {
return false; return false;
} }
...@@ -1867,7 +1870,39 @@ GLenum Texture2DArray::getTarget() const ...@@ -1867,7 +1870,39 @@ GLenum Texture2DArray::getTarget() const
void Texture2DArray::generateMipmaps() void Texture2DArray::generateMipmaps()
{ {
UNIMPLEMENTED(); int depth = image[0] ? image[0]->getDepth() : 0;
if(!depth)
{
return; // FIXME: error?
}
unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
for(unsigned int i = 1; i <= q; i++)
{
if(image[i])
{
image[i]->unbind(this);
}
GLsizei w = std::max(image[0]->getWidth() >> i, 1);
GLsizei h = std::max(image[0]->getHeight() >> i, 1);
image[i] = new egl::Image(this, w, h, depth, image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
return error(GL_OUT_OF_MEMORY);
}
GLsizei srcw = image[i - 1]->getWidth();
GLsizei srch = image[i - 1]->getHeight();
for(int z = 0; z < depth; ++z)
{
sw::SliceRect srcRect(0, 0, srcw, srch, z);
sw::SliceRect dstRect(0, 0, w, h, z);
getDevice()->stretchRect(image[i - 1], &srcRect, image[i], &dstRect, true);
}
}
} }
TextureExternal::TextureExternal(GLuint name) : Texture2D(name) TextureExternal::TextureExternal(GLuint name) : Texture2D(name)
......
...@@ -2414,10 +2414,9 @@ void GenerateMipmap(GLenum target) ...@@ -2414,10 +2414,9 @@ void GenerateMipmap(GLenum target)
} }
else else
{ {
UNIMPLEMENTED(); texture = context->getTexture2DArray();
texture = context->getTexture3D();
break;
} }
break;
case GL_TEXTURE_3D_OES: case GL_TEXTURE_3D_OES:
texture = context->getTexture3D(); texture = context->getTexture3D();
break; break;
...@@ -3716,10 +3715,9 @@ void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) ...@@ -3716,10 +3715,9 @@ void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
} }
else else
{ {
UNIMPLEMENTED(); texture = context->getTexture2DArray();
texture = context->getTexture3D();
break;
} }
break;
case GL_TEXTURE_3D_OES: case GL_TEXTURE_3D_OES:
texture = context->getTexture3D(); texture = context->getTexture3D();
break; break;
...@@ -3863,10 +3861,9 @@ void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) ...@@ -3863,10 +3861,9 @@ void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
} }
else else
{ {
UNIMPLEMENTED(); texture = context->getTexture2DArray();
texture = context->getTexture3D();
break;
} }
break;
case GL_TEXTURE_3D_OES: case GL_TEXTURE_3D_OES:
texture = context->getTexture3D(); texture = context->getTexture3D();
break; break;
...@@ -5955,10 +5952,9 @@ void TexParameterf(GLenum target, GLenum pname, GLfloat param) ...@@ -5955,10 +5952,9 @@ void TexParameterf(GLenum target, GLenum pname, GLfloat param)
} }
else else
{ {
UNIMPLEMENTED(); texture = context->getTexture2DArray();
texture = context->getTexture3D();
break;
} }
break;
case GL_TEXTURE_3D_OES: case GL_TEXTURE_3D_OES:
texture = context->getTexture3D(); texture = context->getTexture3D();
break; break;
...@@ -6111,10 +6107,9 @@ void TexParameteri(GLenum target, GLenum pname, GLint param) ...@@ -6111,10 +6107,9 @@ void TexParameteri(GLenum target, GLenum pname, GLint param)
} }
else else
{ {
UNIMPLEMENTED(); texture = context->getTexture2DArray();
texture = context->getTexture3D();
break;
} }
break;
case GL_TEXTURE_3D_OES: case GL_TEXTURE_3D_OES:
texture = context->getTexture3D(); texture = context->getTexture3D();
break; break;
......
...@@ -368,7 +368,7 @@ namespace sw ...@@ -368,7 +368,7 @@ namespace sw
bool Sampler::hasVolumeTexture() const bool Sampler::hasVolumeTexture() const
{ {
return textureType == TEXTURE_3D; return textureType == TEXTURE_3D || textureType == TEXTURE_2D_ARRAY;
} }
const Texture &Sampler::getTextureData() const Texture &Sampler::getTextureData()
......
...@@ -63,7 +63,7 @@ namespace sw ...@@ -63,7 +63,7 @@ namespace sw
#endif #endif
bool cubeTexture = state.textureType == TEXTURE_CUBE; bool cubeTexture = state.textureType == TEXTURE_CUBE;
bool volumeTexture = state.textureType == TEXTURE_3D; bool volumeTexture = state.textureType == TEXTURE_3D || state.textureType == TEXTURE_2D_ARRAY;
Float4 uuuu = u; Float4 uuuu = u;
Float4 vvvv = v; Float4 vvvv = v;
...@@ -302,7 +302,7 @@ namespace sw ...@@ -302,7 +302,7 @@ namespace sw
#endif #endif
bool cubeTexture = state.textureType == TEXTURE_CUBE; bool cubeTexture = state.textureType == TEXTURE_CUBE;
bool volumeTexture = state.textureType == TEXTURE_3D; bool volumeTexture = state.textureType == TEXTURE_3D || state.textureType == TEXTURE_2D_ARRAY;
if(state.textureType == TEXTURE_NULL) if(state.textureType == TEXTURE_NULL)
{ {
...@@ -590,7 +590,7 @@ namespace sw ...@@ -590,7 +590,7 @@ namespace sw
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], bool lodProvided)
{ {
bool volumeTexture = state.textureType == TEXTURE_3D; bool volumeTexture = state.textureType == TEXTURE_3D || state.textureType == TEXTURE_2D_ARRAY;
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, lodProvided);
...@@ -744,7 +744,7 @@ namespace sw ...@@ -744,7 +744,7 @@ namespace sw
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, Float &lod, Int face[4], bool secondLOD)
{ {
if(state.textureType != TEXTURE_3D) if(state.textureType != TEXTURE_3D && state.textureType != TEXTURE_2D_ARRAY)
{ {
sampleQuad2D(texture, c, u, v, lod, face, secondLOD); sampleQuad2D(texture, c, u, v, lod, face, secondLOD);
} }
...@@ -977,7 +977,7 @@ namespace sw ...@@ -977,7 +977,7 @@ namespace sw
address(uuuu, u_, state.addressingModeU); address(uuuu, u_, state.addressingModeU);
address(vvvv, v_, state.addressingModeV); address(vvvv, v_, state.addressingModeV);
address(wwww, w_, state.addressingModeW); addressW(wwww, w_, mipmap);
if(state.textureFilter <= FILTER_POINT) if(state.textureFilter <= FILTER_POINT)
{ {
...@@ -1098,7 +1098,7 @@ namespace sw ...@@ -1098,7 +1098,7 @@ namespace sw
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], bool lodProvided)
{ {
bool volumeTexture = state.textureType == TEXTURE_3D; bool volumeTexture = state.textureType == TEXTURE_3D || state.textureType == TEXTURE_2D_ARRAY;
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, lodProvided);
...@@ -1229,7 +1229,7 @@ namespace sw ...@@ -1229,7 +1229,7 @@ namespace sw
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, Float &lod, Int face[4], bool secondLOD)
{ {
if(state.textureType != TEXTURE_3D) if(state.textureType != TEXTURE_3D && state.textureType != TEXTURE_2D_ARRAY)
{ {
sampleFloat2D(texture, c, u, v, w, lod, face, secondLOD); sampleFloat2D(texture, c, u, v, w, lod, face, secondLOD);
} }
...@@ -1323,7 +1323,7 @@ namespace sw ...@@ -1323,7 +1323,7 @@ namespace sw
address(uuuu, u, state.addressingModeU); address(uuuu, u, state.addressingModeU);
address(vvvv, v, state.addressingModeV); address(vvvv, v, state.addressingModeV);
address(wwww, w, state.addressingModeW); addressW(wwww, w, mipmap);
if(state.textureFilter <= FILTER_POINT) if(state.textureFilter <= FILTER_POINT)
{ {
...@@ -1625,22 +1625,6 @@ namespace sw ...@@ -1625,22 +1625,6 @@ namespace sw
uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv)); uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv));
uuuu = As<Short4>(As<UInt2>(uuuu) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,uFrac))); uuuu = As<Short4>(As<UInt2>(uuuu) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,uFrac)));
uuu2 = As<Short4>(As<UInt2>(uuu2) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,uFrac))); uuu2 = As<Short4>(As<UInt2>(uuu2) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,uFrac)));
if(state.textureType == TEXTURE_3D)
{
wwww = As<UShort4>(wwww) >> *Pointer<Long1>(mipmap + OFFSET(Mipmap,wFrac));
Short4 www2 = wwww;
wwww = As<Short4>(UnpackLow(wwww, wwww));
www2 = As<Short4>(UnpackHigh(www2, www2));
wwww = As<Short4>(As<UInt2>(wwww) >> 16);
www2 = As<Short4>(As<UInt2>(www2) >> 16);
wwww = As<Short4>(As<Int2>(wwww) << *Pointer<Long1>(mipmap + OFFSET(Mipmap,uInt)));
www2 = As<Short4>(As<Int2>(www2) << *Pointer<Long1>(mipmap + OFFSET(Mipmap,uInt)));
wwww = As<Short4>(As<Int2>(wwww) << *Pointer<Long1>(mipmap + OFFSET(Mipmap,vInt))); // FIXME: Combine uInt and vInt shift
www2 = As<Short4>(As<Int2>(www2) << *Pointer<Long1>(mipmap + OFFSET(Mipmap,vInt)));
uuuu = As<Short4>(As<Int2>(uuuu) + As<Int2>(wwww));
uuu2 = As<Short4>(As<Int2>(uuu2) + As<Int2>(www2));
}
} }
else else
{ {
...@@ -1651,10 +1635,14 @@ namespace sw ...@@ -1651,10 +1635,14 @@ namespace sw
uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv)); uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv));
uuuu = As<Short4>(MulAdd(uuuu, *Pointer<Short4>(mipmap + OFFSET(Mipmap,onePitchP)))); uuuu = As<Short4>(MulAdd(uuuu, *Pointer<Short4>(mipmap + OFFSET(Mipmap,onePitchP))));
uuu2 = As<Short4>(MulAdd(uuu2, *Pointer<Short4>(mipmap + OFFSET(Mipmap,onePitchP)))); uuu2 = As<Short4>(MulAdd(uuu2, *Pointer<Short4>(mipmap + OFFSET(Mipmap,onePitchP))));
}
if(state.textureType == TEXTURE_3D) if((state.textureType == TEXTURE_3D) || (state.textureType == TEXTURE_2D_ARRAY))
{ {
wwww = MulHigh(As<UShort4>(wwww), *Pointer<UShort4>(mipmap + OFFSET(Mipmap,depth))); if(state.textureType != TEXTURE_2D_ARRAY)
{
wwww = MulHigh(As<UShort4>(wwww), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth)));
}
Short4 www2 = wwww; Short4 www2 = wwww;
wwww = As<Short4>(UnpackLow(wwww, Short4(0x0000, 0x0000, 0x0000, 0x0000))); wwww = As<Short4>(UnpackLow(wwww, Short4(0x0000, 0x0000, 0x0000, 0x0000)));
www2 = As<Short4>(UnpackHigh(www2, Short4(0x0000, 0x0000, 0x0000, 0x0000))); www2 = As<Short4>(UnpackHigh(www2, Short4(0x0000, 0x0000, 0x0000, 0x0000)));
...@@ -1663,7 +1651,6 @@ namespace sw ...@@ -1663,7 +1651,6 @@ namespace sw
uuuu = As<Short4>(As<Int2>(uuuu) + As<Int2>(wwww)); uuuu = As<Short4>(As<Int2>(uuuu) + As<Int2>(wwww));
uuu2 = As<Short4>(As<Int2>(uuu2) + As<Int2>(www2)); uuu2 = As<Short4>(As<Int2>(uuu2) + As<Int2>(www2));
} }
}
index[0] = Extract(As<Int2>(uuuu), 0); index[0] = Extract(As<Int2>(uuuu), 0);
index[1] = Extract(As<Int2>(uuuu), 1); index[1] = Extract(As<Int2>(uuuu), 1);
...@@ -2071,6 +2058,18 @@ namespace sw ...@@ -2071,6 +2058,18 @@ namespace sw
} }
} }
void SamplerCore::addressW(Short4 &wwww, Float4 &w, Pointer<Byte>& mipmap)
{
if(state.textureType == TEXTURE_2D_ARRAY)
{
wwww = Min(Max(Short4(RoundInt(w)), Short4(0)), *Pointer<Short4>(mipmap + OFFSET(Mipmap, depth)) - Short4(1));
}
else
{
address(wwww, w, state.addressingModeW);
}
}
void SamplerCore::convertFixed12(Short4 &cs, Float4 &cf) void SamplerCore::convertFixed12(Short4 &cs, Float4 &cf)
{ {
cs = RoundShort4(cf * Float4(0x1000)); cs = RoundShort4(cf * Float4(0x1000));
......
...@@ -47,6 +47,7 @@ namespace sw ...@@ -47,6 +47,7 @@ namespace sw
void sampleTexel(Vector4f &c, Short4 &u, Short4 &v, Short4 &s, Float4 &z, 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]);
void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD); void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
void address(Short4 &uuuu, Float4 &uw, AddressingMode addressingMode); void address(Short4 &uuuu, Float4 &uw, AddressingMode addressingMode);
void addressW(Short4 &uuuu, Float4 &uw, Pointer<Byte>& mipmap);
void convertFixed12(Short4 &ci, Float4 &cf); void convertFixed12(Short4 &ci, Float4 &cf);
void convertFixed12(Vector4s &cs, Vector4f &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