Enable OpenGL ES 3.0 context creation.

Bug 19362672

Change-Id: Ie948dd0c26a6a5f65f6e15b75f2376d598129c28
Reviewed-on: https://swiftshader-review.googlesource.com/2287
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/Config.cpp b/src/OpenGL/libEGL/Config.cpp
index 45eb38e..6530e80 100644
--- a/src/OpenGL/libEGL/Config.cpp
+++ b/src/OpenGL/libEGL/Config.cpp
@@ -81,7 +81,7 @@
     mColorBufferType = EGL_RGB_BUFFER;
     mConfigCaveat = isSlowConfig() ? EGL_SLOW_CONFIG : EGL_NONE;
     mConfigID = 0;
-    mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+    mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
 
 	switch (depthStencilFormat)
 	{
@@ -139,7 +139,7 @@
     mNativeRenderable = EGL_FALSE;
     mNativeVisualID = 0;
     mNativeVisualType = 0;
-    mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+    mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
     mSampleBuffers = multiSample ? 1 : 0;
     mSamples = multiSample;
     mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 39017b4..2013e7b 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -400,11 +400,12 @@
 			context = es1::createContext(config, shareContext);
 		}
 	}
-	else if(clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT)
+	else if((clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT) ||
+	        (clientVersion == 3 && config->mRenderableType & EGL_OPENGL_ES3_BIT))
 	{
 		if(es2::createContext != 0)
 		{
-			context = es2::createContext(config, shareContext);
+			context = es2::createContext(config, shareContext, clientVersion);
 		}
 	}
 	else
diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index a7cf892..3cd35d7 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -104,7 +104,7 @@
 	#endif

 

     libGLESv2 = loadLibrary(libGLESv2_lib);

-    es2::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLESv2, "glCreateContext");

+    es2::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*, EGLint))getProcAddress(libGLESv2, "glCreateContext");

     es2::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress");

 

 	es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLES_CM, "createBackBuffer");

@@ -342,7 +342,7 @@
 

 namespace es2

 {

-	egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;

+	egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext, EGLint clientVersion) = 0;

 	__eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;

 }

 

diff --git a/src/OpenGL/libEGL/main.h b/src/OpenGL/libEGL/main.h
index fbdc014..f6d74d5 100644
--- a/src/OpenGL/libEGL/main.h
+++ b/src/OpenGL/libEGL/main.h
@@ -92,7 +92,7 @@
 // libGLESv2 dependencies
 namespace es2
 {
-	extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext);
+	extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext, EGLint clientVersion);
 	extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname);
 }
 
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 586f238..14808e7 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -39,7 +39,8 @@
 

 namespace es2

 {

-Context::Context(const egl::Config *config, const Context *shareContext) : mConfig(config)

+Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)

+	: mConfig(config), clientVersion(clientVersion)

 {

 	sw::Context *context = new sw::Context();

 	device = new es2::Device(context);

@@ -272,9 +273,9 @@
 	delete this;

 }

 

-int Context::getClientVersion()

+EGLint Context::getClientVersion()

 {

-	return 2;

+	return clientVersion;

 }

 

 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.

@@ -3245,8 +3246,8 @@
 // Exported functions for use by EGL

 extern "C"

 {

-	es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext)

+	es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext, int clientVersion)

 	{

-		return new es2::Context(config, shareContext);

+		return new es2::Context(config, shareContext, clientVersion);

 	}

 }

diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 5d25b40..434644c 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -251,11 +251,11 @@
 class Context : public egl::Context

 {

 public:

-    Context(const egl::Config *config, const Context *shareContext);

+    Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion);

 

 	virtual void makeCurrent(egl::Surface *surface);

 	virtual void destroy();

-	virtual int getClientVersion();

+	virtual EGLint getClientVersion();

 

     void markAllStateDirty();

 

@@ -459,6 +459,7 @@
     bool cullSkipsDraw(GLenum drawMode);

     bool isTriangleMode(GLenum drawMode);

 

+	const EGLint clientVersion;

     const egl::Config *const mConfig;

 

     State mState;

diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 9cb3f10..c781480 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -4086,106 +4086,109 @@
 		return error(GL_INVALID_VALUE);

 	}

 

-	if(internalformat != format)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	switch(format)

-	{

-	case GL_ALPHA:

-	case GL_LUMINANCE:

-	case GL_LUMINANCE_ALPHA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_FLOAT:

-		case GL_HALF_FLOAT_OES:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGB:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_5_6_5:

-		case GL_FLOAT:

-		case GL_HALF_FLOAT_OES:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGBA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-		case GL_FLOAT:

-		case GL_HALF_FLOAT_OES:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_BGRA_EXT:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_ETC1_RGB8_OES:

-		return error(GL_INVALID_OPERATION);

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

-	case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

-		if(S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-		else

-		{

-			return error(GL_INVALID_ENUM);

-		}

-	case GL_DEPTH_COMPONENT:

-		switch(type)

-		{

-		case GL_UNSIGNED_SHORT:

-		case GL_UNSIGNED_INT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_DEPTH_STENCIL_OES:

-		switch(type)

-		{

-		case GL_UNSIGNED_INT_24_8_OES:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

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

 

 	if(context)

 	{

+		if(context->getClientVersion() < 3)

+		{

+			if(internalformat != format)

+			{

+				return error(GL_INVALID_OPERATION);

+			}

+		}

+

+		switch(format)

+		{

+		case GL_ALPHA:

+		case GL_LUMINANCE:

+		case GL_LUMINANCE_ALPHA:

+			switch(type)

+			{

+			case GL_UNSIGNED_BYTE:

+			case GL_FLOAT:

+			case GL_HALF_FLOAT_OES:

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+			break;

+		case GL_RGB:

+			switch(type)

+			{

+			case GL_UNSIGNED_BYTE:

+			case GL_UNSIGNED_SHORT_5_6_5:

+			case GL_FLOAT:

+			case GL_HALF_FLOAT_OES:

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+			break;

+		case GL_RGBA:

+			switch(type)

+			{

+			case GL_UNSIGNED_BYTE:

+			case GL_UNSIGNED_SHORT_4_4_4_4:

+			case GL_UNSIGNED_SHORT_5_5_5_1:

+			case GL_FLOAT:

+			case GL_HALF_FLOAT_OES:

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+			break;

+		case GL_BGRA_EXT:

+			switch(type)

+			{

+			case GL_UNSIGNED_BYTE:

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+			break;

+		case GL_ETC1_RGB8_OES:

+			return error(GL_INVALID_OPERATION);

+		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

+		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:

+		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:

+			if(S3TC_SUPPORT)

+			{

+				return error(GL_INVALID_OPERATION);

+			}

+			else

+			{

+				return error(GL_INVALID_ENUM);

+			}

+		case GL_DEPTH_COMPONENT:

+			switch(type)

+			{

+			case GL_UNSIGNED_SHORT:

+			case GL_UNSIGNED_INT:

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+			break;

+		case GL_DEPTH_STENCIL_OES:

+			switch(type)

+			{

+			case GL_UNSIGNED_INT_24_8_OES:

+				break;

+			default:

+				return error(GL_INVALID_ENUM);

+			}

+			break;

+		default:

+			return error(GL_INVALID_VALUE);

+		}

+

+		if(border != 0)

+		{

+			return error(GL_INVALID_VALUE);

+		}

+

 		switch(target)

 		{

 		case GL_TEXTURE_2D:

diff --git a/src/OpenGL/libGLESv2/main.cpp b/src/OpenGL/libGLESv2/main.cpp
index e351580..9ab0ed9 100644
--- a/src/OpenGL/libGLESv2/main.cpp
+++ b/src/OpenGL/libGLESv2/main.cpp
@@ -109,7 +109,8 @@
 {

 	egl::Context *context = egl::getCurrentContext();

 

-	if(context && context->getClientVersion() == 2)

+	if(context && (context->getClientVersion() == 2 ||

+	               context->getClientVersion() == 3))

 	{

 		return static_cast<es2::Context*>(context);

 	}