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