Support RGB formats with IOSurface client buffer surfaces.

Chrome has started requesting RGB formats for IOSurfaces to support the alpha=false
flag for WebGL context creation.

BUG=chromium:995142

Change-Id: I0c9d994f2d8208e87a0d167ebc0787fc15add08f
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35389
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/extensions/EGL_ANGLE_iosurface_client_buffer.txt b/extensions/EGL_ANGLE_iosurface_client_buffer.txt
index 85daac2..8206eab 100644
--- a/extensions/EGL_ANGLE_iosurface_client_buffer.txt
+++ b/extensions/EGL_ANGLE_iosurface_client_buffer.txt
@@ -10,6 +10,7 @@
 
     Corentin Wallez
     Geoff Lang
+    James Darpinian
 
 Contacts
 
@@ -20,8 +21,7 @@
     Draft
 
 Version
-
-    Version 2, Aug 1, 2019
+    Version 3, Aug 13, 2019
 
 Number
 
@@ -96,6 +96,7 @@
     GL_UNSIGNED_BYTE           GL_RED
     GL_UNSIGNED_SHORT          GL_R16UI
     GL_UNSIGNED_BYTE           GL_RG
+    GL_UNSIGNED_BYTE           GL_RGB
     GL_UNSIGNED_BYTE           GL_BGRA_EXT
     GL_HALF_FLOAT              GL_RGBA
     ---------------------------------------------------------------------------
@@ -110,9 +111,14 @@
 
 Issues
 
-    There are no issues, please move on.
+    1. Can RGB formats be supported?
+
+    RESOLVED: Support for RGB internal formats is added in version 3. Surfaces
+    with an RGB format will ensure that the alpha channel of the IOSurface is
+    reset to 1.0 when it is used.
 
 Revision History
 
     Version 1, 2017/12/06 - first draft.
-    Version 2, 2019/08/01 - allow MakeCurrent
+    Version 2, 2019/04/01 - Allow MakeCurrent.
+    Version 3, 2019/08/13 - Allow RGB internal formats
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index 67de762..695a825 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -1233,6 +1233,7 @@
 			{
 			case sw::FORMAT_R8:            return GL_R8;
 			case sw::FORMAT_G8R8:          return GL_RG8;
+			case sw::FORMAT_X8R8G8B8:      return GL_RGB8;
 			case sw::FORMAT_A8R8G8B8:      return GL_BGRA8_EXT;
 			case sw::FORMAT_R16UI:         return GL_R16UI;
 			case sw::FORMAT_A16B16G16R16F: return GL_RGBA16F;
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 99503ea..eeb44e5 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -381,6 +381,7 @@
 				case GL_RED:
 				case GL_R16UI:
 				case GL_RG:
+				case GL_RGB:
 				case GL_BGRA_EXT:
 				case GL_RGBA:
 					clientBufferFormat = attribList[1];
@@ -470,6 +471,7 @@
 			{
 			case GL_RED:
 			case GL_RG:
+			case GL_RGB:
 			case GL_BGRA_EXT:
 				break;
 			case GL_R16UI:
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index dd912ed..17fc234 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -250,6 +250,8 @@
 			return sw::FORMAT_R8;
 		case GL_RG:
 			return sw::FORMAT_G8R8;
+		case GL_RGB:
+			return sw::FORMAT_X8R8G8B8;
 		case GL_BGRA_EXT:
 			return sw::FORMAT_A8R8G8B8;
 		default:
diff --git a/tests/GLESUnitTests/unittests.cpp b/tests/GLESUnitTests/unittests.cpp
index 97e5520..bfd2112 100644
--- a/tests/GLESUnitTests/unittests.cpp
+++ b/tests/GLESUnitTests/unittests.cpp
@@ -2255,6 +2255,34 @@
 	Uninitialize();
 }
 
+// Test using RGBX8888 IOSurfaces for rendering
+TEST_F(IOSurfaceClientBufferTest, RenderToRGBX8888IOSurface)
+{
+	Initialize(3, false);
+
+	{ // EGLClientBufferWrapper scope
+		EGLClientBufferWrapper clientBufferWrapper;
+		unsigned char data[3] = { 1, 2, 3 };
+		doClearTest(clientBufferWrapper, GL_RGB, GL_UNSIGNED_BYTE, data, 3);
+	} // end of EGLClientBufferWrapper scope
+
+	Uninitialize();
+}
+
+// Test reading from RGBX8888 IOSurfaces
+TEST_F(IOSurfaceClientBufferTest, ReadFromRGBX8888IOSurface)
+{
+	Initialize(3, false);
+
+	{ // EGLClientBufferWrapper scope
+		EGLClientBufferWrapper clientBufferWrapper;
+		unsigned char data[3] = { 1, 2, 3 };
+		doSampleTest(clientBufferWrapper, GL_RGB, GL_UNSIGNED_BYTE, data, 3);
+	} // end of EGLClientBufferWrapper scope
+
+	Uninitialize();
+}
+
 // Test using RG88 IOSurfaces for rendering
 TEST_F(IOSurfaceClientBufferTest, RenderToRG88IOSurface)
 {