Texture 1D implementation in LibGL

Change-Id: I01df347a86d12f38f9ba7761bbd367c96014ff46
Reviewed-on: https://swiftshader-review.googlesource.com/3724
Reviewed-by: Maxime Grégoire <mgregoire@google.com>
Tested-by: Maxime Grégoire <mgregoire@google.com>
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
index 3ceae07..c23420e 100644
--- a/src/OpenGL/libGL/Context.cpp
+++ b/src/OpenGL/libGL/Context.cpp
@@ -137,6 +137,7 @@
     mTexture2DZero = new Texture2D(0);

     mProxyTexture2DZero = new Texture2D(0);

     mTextureCubeMapZero = new TextureCubeMap(0);

+	mTexture1DZero = new Texture1D(0);

 

     mState.activeSampler = 0;

     bindArrayBuffer(0);

@@ -253,6 +254,7 @@
     mTexture2DZero = NULL;

 	mProxyTexture2DZero = NULL;

     mTextureCubeMapZero = NULL;

+	mTexture1DZero = NULL;

 

     delete mVertexDataManager;

     delete mIndexDataManager;

@@ -992,6 +994,13 @@
     mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);

 }

 

+void Context::bindTexture1D(GLuint texture)

+{

+    mResourceManager->checkTextureAllocation(texture, TEXTURE_1D);

+

+    mState.samplerTexture[TEXTURE_1D][mState.activeSampler] = getTexture(texture);

+}

+

 void Context::bindReadFramebuffer(GLuint framebuffer)

 {

     if(!getFramebuffer(framebuffer))

@@ -1223,6 +1232,11 @@
     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));

 }

 

+Texture1D *Context::getTexture1D()

+{

+    return static_cast<Texture1D*>(getSamplerTexture(mState.activeSampler, TEXTURE_1D));

+}

+

 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)

 {

     GLuint texid = mState.samplerTexture[type][sampler].name();

@@ -1234,6 +1248,7 @@
         case TEXTURE_2D:       return mTexture2DZero;

         case PROXY_TEXTURE_2D: return mProxyTexture2DZero;

         case TEXTURE_CUBE:     return mTextureCubeMapZero;

+		case TEXTURE_1D:	   return mTexture1DZero;

         default: UNREACHABLE();

         }

     }

@@ -1615,6 +1630,7 @@
       case GL_SAMPLES:

       case GL_IMPLEMENTATION_COLOR_READ_TYPE:

       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:

+	  case GL_TEXTURE_BINDING_1D:

       case GL_TEXTURE_BINDING_2D:

       case GL_TEXTURE_BINDING_CUBE_MAP:

       case GL_MAX_VERTEX_UNIFORM_COMPONENTS:

@@ -3293,6 +3309,16 @@
 	device->setNormalizeNormals(enable);

 }

 

+void Context::set1DTextureEnable(bool enable)

+{

+	device->set1DTextureEnable(enable);

+}

+

+bool Context::get1DTextureEnable()

+{

+	return device->get1DTextureEnable();

+}

+

 GLuint Context::genLists(GLsizei range)

 {

 	if(drawing)

diff --git a/src/OpenGL/libGL/Context.h b/src/OpenGL/libGL/Context.h
index 7d74fc5..3163c5e 100644
--- a/src/OpenGL/libGL/Context.h
+++ b/src/OpenGL/libGL/Context.h
@@ -22,6 +22,7 @@
 #include "Renderer/Sampler.hpp"

 #include "Renderer/Vertex.hpp"

 #include "common/MatrixStack.hpp"

+#include "Texture.h"

 

 #define _GDI32_

 #include <windows.h>

@@ -612,6 +613,7 @@
     void deleteQuery(GLuint query);

 

     void bindArrayBuffer(GLuint buffer);

+    void bindTexture1D(GLuint texture);

     void bindElementArrayBuffer(GLuint buffer);

     void bindTexture2D(GLuint texture);

     void bindTextureCubeMap(GLuint texture);

@@ -641,6 +643,7 @@
     Buffer *getArrayBuffer();

     Buffer *getElementArrayBuffer();

     Program *getCurrentProgram();

+    Texture1D *getTexture1D();

     Texture2D *getTexture2D(GLenum target);

     TextureCubeMap *getTextureCubeMap();

     Texture *getSamplerTexture(unsigned int sampler, TextureType type);

@@ -694,6 +697,8 @@
 	void setShadeModel(GLenum mode);

     void setLight(int index, bool enable);

 	void setNormalizeNormals(bool enable);

+    void set1DTextureEnable(bool enable);

+    bool get1DTextureEnable();

 

 	GLuint genLists(GLsizei range);

 	void newList(GLuint list, GLenum mode);

@@ -740,6 +745,7 @@
 

     State mState;

 

+    BindingPointer<Texture1D> mTexture1DZero;

     BindingPointer<Texture2D> mTexture2DZero;

     BindingPointer<Texture2D> mProxyTexture2DZero;

     BindingPointer<TextureCubeMap> mTextureCubeMapZero;

diff --git a/src/OpenGL/libGL/Device.cpp b/src/OpenGL/libGL/Device.cpp
index cd314d2..60a2967 100644
--- a/src/OpenGL/libGL/Device.cpp
+++ b/src/OpenGL/libGL/Device.cpp
@@ -157,6 +157,8 @@
         setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

         setAmbientMaterialSource(sw::MATERIAL_COLOR1);

         setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

+

+		oneDTextureEnable = false;

 	}

 

 	Device::~Device()

@@ -441,6 +443,16 @@
 		scissorEnable = enable;

 	}

 

+	void Device::set1DTextureEnable(bool enable)

+	{

+		oneDTextureEnable = enable;

+	}

+

+	bool Device::get1DTextureEnable()

+	{

+		return oneDTextureEnable;

+	}

+

 	void Device::setRenderTarget(Image *renderTarget)

 	{

 		if(renderTarget)

diff --git a/src/OpenGL/libGL/Device.hpp b/src/OpenGL/libGL/Device.hpp
index dec8dfb..119046c 100644
--- a/src/OpenGL/libGL/Device.hpp
+++ b/src/OpenGL/libGL/Device.hpp
@@ -59,6 +59,8 @@
 		virtual void setPixelShader(sw::PixelShader *shader);

 		virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);

 		virtual void setScissorEnable(bool enable);

+		virtual void set1DTextureEnable(bool enable);

+		virtual bool get1DTextureEnable();

 		virtual void setRenderTarget(Image *renderTarget);

 		virtual void setScissorRect(const sw::Rect &rect);

 		virtual void setVertexShader(sw::VertexShader *shader);

diff --git a/src/OpenGL/libGL/ResourceManager.cpp b/src/OpenGL/libGL/ResourceManager.cpp
index 383a66f..9f39fd9 100644
--- a/src/OpenGL/libGL/ResourceManager.cpp
+++ b/src/OpenGL/libGL/ResourceManager.cpp
@@ -323,7 +323,11 @@
     {
         Texture *textureObject;
 
-        if(type == TEXTURE_2D)
+		if(type == TEXTURE_1D)
+		{
+			textureObject = new Texture1D(texture);
+		}
+        else if(type == TEXTURE_2D)
         {
             textureObject = new Texture2D(texture);
         }
diff --git a/src/OpenGL/libGL/ResourceManager.h b/src/OpenGL/libGL/ResourceManager.h
index 11c85eb..d3c619c 100644
--- a/src/OpenGL/libGL/ResourceManager.h
+++ b/src/OpenGL/libGL/ResourceManager.h
@@ -37,6 +37,7 @@
     TEXTURE_2D,

     PROXY_TEXTURE_2D,

     TEXTURE_CUBE,

+	TEXTURE_1D,

 

     TEXTURE_TYPE_COUNT,

     TEXTURE_UNKNOWN

diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index 74c1daa..a11a3fc 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -168,11 +168,11 @@
     return mMaxAnisotropy;

 }

 

-void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)

+void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image, int xOffset)

 {

     if(pixels && image)

     {

-		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);

+		image->loadImageData(xOffset, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);

     }

 }

 

@@ -184,7 +184,7 @@
     }

 }

 

-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)

+void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image, bool is2DTexture)

 {

 	if(!image)

 	{

@@ -201,7 +201,7 @@
         return error(GL_INVALID_OPERATION);

     }

 

-    if(format != image->getFormat())

+	if(format != image->getFormat() && is2DTexture)

     {

         return error(GL_INVALID_OPERATION);

     }

@@ -367,7 +367,7 @@
 	return levels;

 }

 

-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, int xOffset)

 {

 	if(image[level])

 	{

@@ -381,7 +381,7 @@
 		return error(GL_OUT_OF_MEMORY);

 	}

 

-    Texture::setImage(format, type, unpackAlignment, pixels, image[level]);

+	Texture::setImage(format, type, unpackAlignment, pixels, image[level], xOffset);

 }

 

 void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

@@ -1038,4 +1038,57 @@
 	return image[face][level];

 }

 

+Texture1D::Texture1D(GLuint name) : Texture2D(name)

+{

+}

+

+Texture1D::~Texture1D()

+{

+}

+

+GLenum Texture1D::getTarget() const

+{

+	return GL_TEXTURE_1D;

+}

+

+GLenum Texture1D::getFormat(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_1D);

+	return image[level] ? image[level]->getFormat() : 0;

+}

+

+GLenum Texture1D::getType(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_1D);

+	return image[level] ? image[level]->getType() : 0;

+}

+

+GLsizei Texture1D::getWidth(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);

+	return image[level] ? image[level]->getWidth() : 0;

+}

+

+GLsizei Texture1D::getHeight(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);

+	return image[level] ? image[level]->getHeight() : 0;

+}

+

+sw::Format Texture1D::getInternalFormat(GLenum target, GLint level) const

+{

+	ASSERT(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);

+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

+}

+

+void Texture1D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

+{

+	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level], false);

+}

+

+bool Texture1D::isCompressed(GLenum target, GLint level) const

+{

+	return IsCompressed(getFormat(target, level));

+}

+

 }

diff --git a/src/OpenGL/libGL/Texture.h b/src/OpenGL/libGL/Texture.h
index 2f8ed28..1f79dcb 100644
--- a/src/OpenGL/libGL/Texture.h
+++ b/src/OpenGL/libGL/Texture.h
@@ -88,8 +88,8 @@
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

 

 protected:

-    void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);

-    void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);

+	void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image, int xOffset = 0);

+	void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image, bool is2DTexture = true);

     void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);

     void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);

 

@@ -126,7 +126,7 @@
     virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

 	virtual int getLevelCount() const;

 

-    void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

+	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, int xOffset = 0);

     void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

     void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

@@ -216,6 +216,22 @@
 	unsigned int mFaceProxyRefs[6];

 };

 

+class Texture1D : public Texture2D

+{

+public:

+	explicit Texture1D(GLuint name);

+

+	virtual ~Texture1D();

+	virtual GLenum getTarget() const;

+	virtual GLenum getFormat(GLenum target, GLint level) const;

+	virtual GLenum getType(GLenum target, GLint level) const;

+	virtual GLsizei getWidth(GLenum target, GLint level) const;

+	virtual GLsizei getHeight(GLenum target, GLint level) const;

+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

+	virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

+	virtual bool isCompressed(GLenum target, GLint level) const;

+};

+

 }

 

 #endif   // LIBGL_TEXTURE_H_

diff --git a/src/OpenGL/libGL/libGL.cpp b/src/OpenGL/libGL/libGL.cpp
index 553d0a2..fa3073d 100644
--- a/src/OpenGL/libGL/libGL.cpp
+++ b/src/OpenGL/libGL/libGL.cpp
@@ -55,7 +55,7 @@
 		return error(GL_INVALID_OPERATION, false);

 	}

 

-	if(format != GL_NONE && format != texture->getFormat(target, level))

+	if(format != GL_NONE && format != texture->getFormat(target, level) && target != GL_TEXTURE_1D)

 	{

 		return error(GL_INVALID_OPERATION, false);

 	}

@@ -349,6 +349,9 @@
 

 		switch(target)

 		{

+		case GL_TEXTURE_1D:

+			context->bindTexture1D(texture);

+			return;

 		case GL_TEXTURE_2D:

 			context->bindTexture2D(texture);

 			return;

@@ -1652,6 +1655,7 @@
 

 		switch(cap)

 		{

+		case GL_TEXTURE_1D:               context->set1DTextureEnable(false);       break;

 		case GL_CULL_FACE:                context->setCullFace(false);              break;

 		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(false);     break;

 		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;

@@ -1799,6 +1803,7 @@
 

 		switch(cap)

 		{

+		case GL_TEXTURE_1D:               context->set1DTextureEnable(true);       break;

 		case GL_CULL_FACE:                context->setCullFace(true);              break;

 		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(true);     break;

 		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;

@@ -4395,6 +4400,7 @@
 

 	switch(target)

 	{

+	case GL_TEXTURE_1D:

 	case GL_TEXTURE_2D:

 		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

 		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

@@ -4463,7 +4469,18 @@
 			UNIMPLEMENTED();

 		}

 

-		if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)

+		if(target == GL_TEXTURE_1D)

+		{

+			gl::Texture1D *texture = context->getTexture1D();

+

+			if(!texture)

+			{

+				return error(GL_INVALID_OPERATION);

+			}

+

+			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);

+		}

+		else if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)

 		{

 			gl::Texture2D *texture = context->getTexture2D(target);

 

@@ -4589,6 +4606,9 @@
 

 		switch(target)

 		{

+		case GL_TEXTURE_1D:

+			texture = context->getTexture1D();

+			break;

 		case GL_TEXTURE_2D:

 			texture = context->getTexture2D(target);

 			break;

@@ -4695,7 +4715,16 @@
 			return error(GL_INVALID_VALUE);

 		}

 

-		if(target == GL_TEXTURE_2D)

+		if(target == GL_TEXTURE_1D)

+		{

+			gl::Texture1D *texture = context->getTexture1D();

+

+			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

+			{

+				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);

+			}

+		}

+		else if(target == GL_TEXTURE_2D)

 		{

 			gl::Texture2D *texture = context->getTexture2D(target);

 

@@ -7539,12 +7568,20 @@
 

 void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)

 {

-	UNIMPLEMENTED();

+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "

+		"GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",

+		target, level, internalformat, width, border, format, type, pixels);

+

+	glTexImage2D(target, level, internalformat, width, 1, border, format, type, pixels);

 }

 

 void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)

 {

-	UNIMPLEMENTED();

+	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLsizei width = %d, "

+		"GLenum format =  0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",

+		target, level, xoffset, width, format, type, pixels);

+

+	glTexSubImage2D(target, level, xoffset, 0, width, 1, format, type, pixels);

 }

 

 void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)

diff --git a/src/OpenGL/libGL/utilities.cpp b/src/OpenGL/libGL/utilities.cpp
index 79249f2..eba16dd 100644
--- a/src/OpenGL/libGL/utilities.cpp
+++ b/src/OpenGL/libGL/utilities.cpp
@@ -309,7 +309,7 @@
 

 	bool IsTextureTarget(GLenum target)

 	{

-		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);

+		return target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);

 	}

 

 	// Verify that format/type are one of the combinations from table 3.4.

diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index b10b7a0..be16fca 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -296,6 +296,7 @@
 		bool updateBaseMatrix;

 		bool updateProjectionMatrix;

 		bool updateLighting;

+		bool oneDTextureEnable;

 	};

 }