glGet, 64b version

Implemented glGetInteger[64i_v,64v], which
is very similar to the 32b version, except
it has a 64b output argument.

Change-Id: I1874109da419b82b2499f4d82d9c46ab44381d65
Reviewed-on: https://swiftshader-review.googlesource.com/2864
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 5fcd823..c22386a 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -1690,7 +1690,10 @@
     return true;

 }

 

-bool Context::getIntegerv(GLenum pname, GLint *params) const

+template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;

+template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;

+

+template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const

 {

     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation

     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

@@ -2173,7 +2176,10 @@
     return true;

 }

 

-bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) const

+template bool Context::getTransformFeedbackiv<GLint>(GLuint xfb, GLenum pname, GLint *param) const;

+template bool Context::getTransformFeedbackiv<GLint64>(GLuint xfb, GLenum pname, GLint64 *param) const;

+

+template<typename T> bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, T *param) const

 {

 	UNIMPLEMENTED();

 

diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 0c9706b..575c99c 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -550,9 +550,9 @@
 	Framebuffer *getDrawFramebuffer() const;

 

 	bool getFloatv(GLenum pname, GLfloat *params) const;

-	bool getIntegerv(GLenum pname, GLint *params) const;

+	template<typename T> bool getIntegerv(GLenum pname, T *params) const;

 	bool getBooleanv(GLenum pname, GLboolean *params) const;

-	bool getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) const;

+	template<typename T> bool getTransformFeedbackiv(GLuint xfb, GLenum pname, T *param) const;

 

 	bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const;

 

diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 971dc69..8dfd4b4 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -3028,7 +3028,7 @@
 				{

 					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)

 					{

-						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);

+						params[i] = es2::floatToInt(floatParams[i]);

 					}

 					else

 					{

diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 93596b7..11804eb 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1638,7 +1638,7 @@
 				{

 					if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)

 					{

-						data[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);

+						data[i] = es2::floatToInt(floatParams[i]);

 					}

 					else

 					{

@@ -2788,7 +2788,58 @@
 GL_APICALL void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data)

 {

 	TRACE("(GLenum pname = 0x%X, GLint64 *data = %p)", pname, data);

-	UNIMPLEMENTED();

+

+	es2::Context *context = es2::getContext();

+

+	if(context)

+	{

+		if(!(context->getIntegerv(pname, data)))

+		{

+			GLenum nativeType;

+			unsigned int numParams = 0;

+			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))

+				return error(GL_INVALID_ENUM);

+

+			if(numParams == 0)

+				return; // it is known that pname is valid, but there are no parameters to return

+

+			if(nativeType == GL_BOOL)

+			{

+				GLboolean *boolParams = NULL;

+				boolParams = new GLboolean[numParams];

+

+				context->getBooleanv(pname, boolParams);

+

+				for(unsigned int i = 0; i < numParams; ++i)

+				{

+					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;

+				}

+

+				delete[] boolParams;

+			}

+			else if(nativeType == GL_FLOAT)

+			{

+				GLfloat *floatParams = NULL;

+				floatParams = new GLfloat[numParams];

+

+				context->getFloatv(pname, floatParams);

+

+				for(unsigned int i = 0; i < numParams; ++i)

+				{

+					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)

+					{

+						data[i] = (GLint64)(es2::floatToInt(floatParams[i]));

+					}

+					else

+					{

+						data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

+					}

+				}

+

+				delete[] floatParams;

+			}

+		}

+	}

 }

 

 GL_APICALL void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)

@@ -2802,7 +2853,59 @@
 GL_APICALL void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)

 {

 	TRACE("(GLenum target = 0x%X, GLuint index = %d, GLint64 *data = %p)", target, index, data);

-	UNIMPLEMENTED();

+

+	es2::Context *context = es2::getContext();

+

+	if(context)

+	{

+		if(!context->getTransformFeedbackiv(index, target, data) &&

+			!context->getIntegerv(target, data))

+		{

+			GLenum nativeType;

+			unsigned int numParams = 0;

+			if(!context->getQueryParameterInfo(target, &nativeType, &numParams))

+				return error(GL_INVALID_ENUM);

+

+			if(numParams == 0)

+				return; // it is known that target is valid, but there are no parameters to return

+

+			if(nativeType == GL_BOOL)

+			{

+				GLboolean *boolParams = NULL;

+				boolParams = new GLboolean[numParams];

+

+				context->getBooleanv(target, boolParams);

+

+				for(unsigned int i = 0; i < numParams; ++i)

+				{

+					data[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;

+				}

+

+				delete[] boolParams;

+			}

+			else if(nativeType == GL_FLOAT)

+			{

+				GLfloat *floatParams = NULL;

+				floatParams = new GLfloat[numParams];

+

+				context->getFloatv(target, floatParams);

+

+				for(unsigned int i = 0; i < numParams; ++i)

+				{

+					if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)

+					{

+						data[i] = (GLint64)(es2::floatToInt(floatParams[i]));

+					}

+					else

+					{

+						data[i] = (GLint64)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

+					}

+				}

+

+				delete[] floatParams;

+			}

+		}

+	}

 }

 

 GL_APICALL void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)

diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 9af95cd..86f0c51 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -191,6 +191,11 @@
 		return -1;

 	}

 

+	GLint floatToInt(GLfloat value)

+	{

+		return static_cast<GLint>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) * 0.5f);

+	}

+

 	bool IsCompressed(GLenum format)

 	{

 		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||

diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index b421790..e02d704 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -35,6 +35,8 @@
 

 	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);

 

+	GLint floatToInt(GLfloat value);

+

 	bool IsCompressed(GLenum format);

 	bool IsDepthTexture(GLenum format);

 	bool IsStencilTexture(GLenum format);