Texture2DArray skeleton
Added basic class / enums / function skeletons
for Texture2DArray. No sampling code has been
added to SamplerCore for Texture2DArray yet.
Change-Id: I78bc1fdec069005d2b3b6f6b1ba41db8c278f74b
Reviewed-on: https://swiftshader-review.googlesource.com/2852
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index f62f583..26e243a 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -138,6 +138,7 @@
mTexture2DZero = new Texture2D(0);
mTexture3DZero = new Texture3D(0);
+ mTexture2DArrayZero = new Texture2DArray(0);
mTextureCubeMapZero = new TextureCubeMap(0);
mTextureExternalZero = new TextureExternal(0);
@@ -252,6 +253,7 @@
mTexture2DZero = NULL;
mTexture3DZero = NULL;
+ mTexture2DArrayZero = NULL;
mTextureCubeMapZero = NULL;
mTextureExternalZero = NULL;
@@ -1587,6 +1589,11 @@
return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
}
+Texture2DArray *Context::getTexture2DArray() const
+{
+ return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
+}
+
TextureCubeMap *Context::getTextureCubeMap() const
{
return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
@@ -1607,6 +1614,7 @@
{
case TEXTURE_2D: return mTexture2DZero;
case TEXTURE_3D: return mTexture3DZero;
+ case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
case TEXTURE_CUBE: return mTextureCubeMapZero;
case TEXTURE_EXTERNAL: return mTextureExternalZero;
default: UNREACHABLE();
@@ -2953,6 +2961,27 @@
device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
}
}
+ else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY)
+ {
+ Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
+
+ for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
+ {
+ int surfaceLevel = mipmapLevel;
+
+ if(surfaceLevel < 0)
+ {
+ surfaceLevel = 0;
+ }
+ else if(surfaceLevel >= levelCount)
+ {
+ surfaceLevel = levelCount - 1;
+ }
+
+ egl::Image *surface = texture->getImage(surfaceLevel);
+ device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
+ }
+ }
else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
{
for(int face = 0; face < 6; face++)
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 9b3a30d..8e6593c 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -50,6 +50,7 @@
class Texture;
class Texture2D;
class Texture3D;
+class Texture2DArray;
class TextureCubeMap;
class TextureExternal;
class Framebuffer;
@@ -549,6 +550,7 @@
Program *getCurrentProgram() const;
Texture2D *getTexture2D() const;
Texture3D *getTexture3D() const;
+ Texture2DArray *getTexture2DArray() const;
TextureCubeMap *getTextureCubeMap() const;
TextureExternal *getTextureExternal() const;
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
@@ -622,6 +624,7 @@
gl::BindingPointer<Texture2D> mTexture2DZero;
gl::BindingPointer<Texture3D> mTexture3DZero;
+ gl::BindingPointer<Texture2DArray> mTexture2DArrayZero;
gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;
gl::BindingPointer<TextureExternal> mTextureExternalZero;
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.cpp b/src/OpenGL/libGLESv2/Renderbuffer.cpp
index 2ae4435..2fae03f 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.cpp
+++ b/src/OpenGL/libGLESv2/Renderbuffer.cpp
@@ -162,39 +162,39 @@
// caller must release() the returned image
egl::Image *RenderbufferTexture3D::getRenderTarget()
{
- return mTexture3D->getRenderTarget(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->getRenderTarget(mTexture3D->getTarget(), 0);
}
// Increments refcount on image.
// caller must release() the returned image
egl::Image *RenderbufferTexture3D::createSharedImage()
{
- return mTexture3D->createSharedImage(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->createSharedImage(mTexture3D->getTarget(), 0);
}
bool RenderbufferTexture3D::isShared() const
{
- return mTexture3D->isShared(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->isShared(mTexture3D->getTarget(), 0);
}
GLsizei RenderbufferTexture3D::getWidth() const
{
- return mTexture3D->getWidth(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->getWidth(mTexture3D->getTarget(), 0);
}
GLsizei RenderbufferTexture3D::getHeight() const
{
- return mTexture3D->getHeight(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->getHeight(mTexture3D->getTarget(), 0);
}
GLenum RenderbufferTexture3D::getFormat() const
{
- return mTexture3D->getFormat(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->getFormat(mTexture3D->getTarget(), 0);
}
sw::Format RenderbufferTexture3D::getInternalFormat() const
{
- return mTexture3D->getInternalFormat(GL_TEXTURE_3D_OES, 0);
+ return mTexture3D->getInternalFormat(mTexture3D->getTarget(), 0);
}
GLsizei RenderbufferTexture3D::getSamples() const
diff --git a/src/OpenGL/libGLESv2/ResourceManager.cpp b/src/OpenGL/libGLESv2/ResourceManager.cpp
index 4f6b177..e0f7ce0 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.cpp
+++ b/src/OpenGL/libGLESv2/ResourceManager.cpp
@@ -315,6 +315,10 @@
{
textureObject = new Texture3D(texture);
}
+ else if(type == TEXTURE_2D_ARRAY)
+ {
+ textureObject = new Texture2DArray(texture);
+ }
else
{
UNREACHABLE();
diff --git a/src/OpenGL/libGLESv2/ResourceManager.h b/src/OpenGL/libGLESv2/ResourceManager.h
index b1517c5..a3d04e5 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.h
+++ b/src/OpenGL/libGLESv2/ResourceManager.h
@@ -33,6 +33,7 @@
{
TEXTURE_2D,
TEXTURE_3D,
+ TEXTURE_2D_ARRAY,
TEXTURE_CUBE,
TEXTURE_EXTERNAL,
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 2d909e6..c74ba43 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -10,8 +10,8 @@
//
// Texture.cpp: Implements the Texture class and its derived classes
-// Texture2D, TextureCubeMap and Texture3D. Implements GL texture objects and related
-// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+// Texture2D, TextureCubeMap, Texture3D and Texture2DArray. Implements GL texture objects
+// and related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
#include "Texture.h"
@@ -402,7 +402,7 @@
{
if(pixels && image)
{
- GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES) ? image->getDepth() : 1;
+ GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackAlignment, pixels);
}
}
@@ -411,7 +411,7 @@
{
if(pixels && image)
{
- GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES) ? image->getDepth() : 1;
+ GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), depth, imageSize, pixels);
}
}
@@ -1460,37 +1460,37 @@
GLsizei Texture3D::getWidth(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getWidth() : 0;
}
GLsizei Texture3D::getHeight(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getHeight() : 0;
}
GLsizei Texture3D::getDepth(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getDepth() : 0;
}
GLenum Texture3D::getFormat(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getFormat() : 0;
}
GLenum Texture3D::getType(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getType() : 0;
}
sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
}
@@ -1803,7 +1803,7 @@
Renderbuffer *Texture3D::getRenderbuffer(GLenum target)
{
- if(target != GL_TEXTURE_3D_OES)
+ if(target != getTarget())
{
return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
@@ -1818,7 +1818,7 @@
egl::Image *Texture3D::getRenderTarget(GLenum target, unsigned int level)
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(image[level])
@@ -1831,7 +1831,7 @@
bool Texture3D::isShared(GLenum target, unsigned int level) const
{
- ASSERT(target == GL_TEXTURE_3D_OES);
+ ASSERT(target == getTarget());
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(mSurface) // Bound to an EGLSurface
@@ -1847,6 +1847,24 @@
return image[level]->isShared();
}
+Texture2DArray::Texture2DArray(GLuint name) : Texture3D(name)
+{
+}
+
+Texture2DArray::~Texture2DArray()
+{
+}
+
+GLenum Texture2DArray::getTarget() const
+{
+ return GL_TEXTURE_2D_ARRAY;
+}
+
+void Texture2DArray::generateMipmaps()
+{
+ UNIMPLEMENTED();
+}
+
TextureExternal::TextureExternal(GLuint name) : Texture2D(name)
{
mMinFilter = GL_LINEAR;
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 81fdf92..3640c15 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -326,6 +326,17 @@
unsigned int mProxyRefs;
};
+class Texture2DArray : public Texture3D
+{
+public:
+ explicit Texture2DArray(GLuint name);
+
+ virtual ~Texture2DArray();
+
+ virtual GLenum getTarget() const;
+ virtual void generateMipmaps();
+};
+
class TextureExternal : public Texture2D
{
public:
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 3381e2d..4ff690c 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -598,7 +598,7 @@
if(context)
{
- es2::Texture3D *texture = context->getTexture3D();
+ es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
if(!texture)
{
@@ -644,7 +644,7 @@
if(context)
{
- es2::Texture3D *texture = context->getTexture3D();
+ es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))
{
@@ -692,7 +692,7 @@
}
GLenum colorbufferFormat = source->getFormat();
- es2::Texture3D *texture = context->getTexture3D();
+ es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))
{
@@ -778,7 +778,7 @@
if(context)
{
- es2::Texture3D *texture = context->getTexture3D();
+ es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
if(!texture)
{
@@ -846,7 +846,7 @@
if(context)
{
- es2::Texture3D *texture = context->getTexture3D();
+ es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
if(!texture)
{
@@ -3834,7 +3834,7 @@
return error(GL_INVALID_OPERATION);
}
- es2::Texture3D *texture = context->getTexture3D();
+ es2::Texture3D *texture = context->getTexture2DArray();
if(!texture || texture->name == 0 || texture->getImmutableFormat())
{
return error(GL_INVALID_OPERATION);
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp
index f51229c..7cb0ab6 100644
--- a/src/Renderer/Sampler.hpp
+++ b/src/Renderer/Sampler.hpp
@@ -78,8 +78,9 @@
TEXTURE_2D,
TEXTURE_CUBE,
TEXTURE_3D,
+ TEXTURE_2D_ARRAY,
- TEXTURE_LAST = TEXTURE_3D
+ TEXTURE_LAST = TEXTURE_2D_ARRAY
};
enum FilterType : unsigned int