Implement missing EGL surface queries.

Fixes dEQP-EGL.functional.query_surface.* tests.

Change-Id: I9d0d2dee83140613af24471d350777959ee37565
Reviewed-on: https://swiftshader-review.googlesource.com/18488
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libEGL/Config.cpp b/src/OpenGL/libEGL/Config.cpp
index 2595ef1..d7fb273 100644
--- a/src/OpenGL/libEGL/Config.cpp
+++ b/src/OpenGL/libEGL/Config.cpp
@@ -181,7 +181,7 @@
 	mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
 	mSampleBuffers = (multiSample > 0) ? 1 : 0;
 	mSamples = multiSample;
-	mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+	mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT;
 	mTransparentType = EGL_NONE;
 	mTransparentRedValue = 0;
 	mTransparentGreenValue = 0;
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index a5c87b9..6be01ac 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -183,14 +183,10 @@
 
 	for(unsigned int samplesIndex = 0; samplesIndex < sizeof(samples) / sizeof(int); samplesIndex++)
 	{
-		for(unsigned int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(sw::Format); formatIndex++)
+		for(sw::Format renderTargetFormat : renderTargetFormats)
 		{
-			sw::Format renderTargetFormat = renderTargetFormats[formatIndex];
-
-			for(unsigned int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(sw::Format); depthStencilIndex++)
+			for(sw::Format depthStencilFormat : depthStencilFormats)
 			{
-				sw::Format depthStencilFormat = depthStencilFormats[depthStencilIndex];
-
 				configSet.add(currentDisplayFormat, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, samples[samplesIndex]);
 			}
 		}
@@ -425,7 +421,8 @@
 			case EGL_MIPMAP_TEXTURE:
 				if(attribList[1] != EGL_FALSE)
 				{
-					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+					UNIMPLEMENTED();
+					return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
 				}
 				break;
 			case EGL_VG_COLORSPACE:
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index ead75a6..2d090b7 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -51,24 +51,6 @@
 {
 Surface::Surface(const Display *display, const Config *config) : display(display), config(config)
 {
-	backBuffer = nullptr;
-	depthStencil = nullptr;
-	texture = nullptr;
-
-	width = 0;
-	height = 0;
-	largestPBuffer = EGL_FALSE;
-	pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
-	renderBuffer = EGL_BACK_BUFFER;
-	swapBehavior = EGL_BUFFER_PRESERVED;
-	textureFormat = EGL_NO_TEXTURE;
-	textureTarget = EGL_NO_TEXTURE;
-	clientBufferFormat = EGL_NO_TEXTURE;
-	clientBufferType = EGL_NO_TEXTURE;
-	clientBuffer = nullptr;
-	clientBufferPlane = -1;
-	swapInterval = -1;
-	setSwapInterval(1);
 }
 
 Surface::~Surface()
@@ -167,6 +149,16 @@
 	return depthStencil;
 }
 
+void Surface::setMipmapLevel(EGLint mipmapLevel)
+{
+	this->mipmapLevel = mipmapLevel;
+}
+
+void Surface::setMultisampleResolve(EGLenum multisampleResolve)
+{
+	this->multisampleResolve = multisampleResolve;
+}
+
 void Surface::setSwapBehavior(EGLenum swapBehavior)
 {
 	this->swapBehavior = swapBehavior;
@@ -204,6 +196,16 @@
 	return height;
 }
 
+EGLint Surface::getMipmapLevel() const
+{
+	return mipmapLevel;
+}
+
+EGLenum Surface::getMultisampleResolve() const
+{
+	return multisampleResolve;
+}
+
 EGLint Surface::getPixelAspectRatio() const
 {
 	return pixelAspectRatio;
@@ -292,7 +294,7 @@
 WindowSurface::WindowSurface(Display *display, const Config *config, EGLNativeWindowType window)
 	: Surface(display, config), window(window)
 {
-	frameBuffer = nullptr;
+	pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
 }
 
 WindowSurface::~WindowSurface()
diff --git a/src/OpenGL/libEGL/Surface.hpp b/src/OpenGL/libEGL/Surface.hpp
index be43edb..183a104 100644
--- a/src/OpenGL/libEGL/Surface.hpp
+++ b/src/OpenGL/libEGL/Surface.hpp
@@ -40,6 +40,8 @@
 	egl::Image *getRenderTarget() override;
 	egl::Image *getDepthStencil() override;
 
+	void setMipmapLevel(EGLint mipmapLevel);
+	void setMultisampleResolve(EGLenum multisampleResolve);
 	void setSwapBehavior(EGLenum swapBehavior);
 	void setSwapInterval(EGLint interval);
 
@@ -49,6 +51,8 @@
 	EGLint getWidth() const override;
 	EGLint getHeight() const override;
 	EGLenum getTextureTarget() const override;
+	virtual EGLint getMipmapLevel() const;
+	virtual EGLenum getMultisampleResolve() const;
 	virtual EGLint getPixelAspectRatio() const;
 	virtual EGLenum getRenderBuffer() const;
 	virtual EGLenum getSwapBehavior() const;
@@ -73,33 +77,38 @@
 	sw::Format getClientBufferFormat() const;
 
 	const Display *const display;
-	Image *depthStencil;
-	Image *backBuffer;
-	Texture *texture;
+	const Config *const config;
+
+	Image *depthStencil = nullptr;
+	Image *backBuffer = nullptr;
+	Texture *texture = nullptr;
 
 	bool reset(int backbufferWidth, int backbufferHeight);
 
-	const Config *const config;    // EGL config surface was created with
-	EGLint width;                  // Width of surface
-	EGLint height;                 // Height of surface
-//  EGLint horizontalResolution;   // Horizontal dot pitch
-//  EGLint verticalResolution;     // Vertical dot pitch
-	EGLBoolean largestPBuffer;     // If true, create largest pbuffer possible
-//  EGLBoolean mipmapTexture;      // True if texture has mipmaps
-//  EGLint mipmapLevel;            // Mipmap level to render to
-//  EGLenum multisampleResolve;    // Multisample resolve behavior
-	EGLint pixelAspectRatio;       // Display aspect ratio
-	EGLenum renderBuffer;          // Render buffer
-	EGLenum swapBehavior;          // Buffer swap behavior
-	EGLenum textureFormat;         // Format of texture: RGB, RGBA, or no texture
-	EGLenum textureTarget;         // Type of texture: 2D or no texture
+	// Surface attributes:
+	EGLint width = 0;                                // Width of surface
+	EGLint height= 0;                                // Height of surface
+//	EGLint horizontalResolution = EGL_UNKNOWN;       // Horizontal dot pitch
+//	EGLint verticalResolution = EGL_UNKNOWN;         // Vertical dot pitch
+	EGLBoolean largestPBuffer = EGL_FALSE;           // If true, create largest pbuffer possible
+//	EGLBoolean mipmapTexture = EGL_FALSE;            // True if texture has mipmaps
+	EGLint mipmapLevel = 0;                          // Mipmap level to render to
+	EGLenum multisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;   // Multisample resolve behavior
+	EGLint pixelAspectRatio = EGL_UNKNOWN;           // Display aspect ratio
+	EGLenum renderBuffer = EGL_BACK_BUFFER;          // Render buffer
+	EGLenum swapBehavior = EGL_BUFFER_PRESERVED;     // Buffer swap behavior (initial value chosen by implementation)
+	EGLenum textureFormat = EGL_NO_TEXTURE;          // Format of texture: RGB, RGBA, or no texture
+	EGLenum textureTarget = EGL_NO_TEXTURE;          // Type of texture: 2D or no texture
+//	EGLenum vgAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;   // Alpha format for OpenVG
+//	EGLenum vgColorSpace = EGL_VG_COLORSPACE_sRGB;   // Color space for OpenVG
+
+	EGLint swapInterval = 1;
+
+	// EGL_ANGLE_iosurface_client_buffer attributes:
+	EGLClientBuffer clientBuffer = nullptr;
+	EGLint clientBufferPlane;
 	EGLenum clientBufferFormat;    // Format of the client buffer
 	EGLenum clientBufferType;      // Type of the client buffer
-//  EGLenum vgAlphaFormat;         // Alpha format for OpenVG
-//  EGLenum vgColorSpace;          // Color space for OpenVG
-	EGLint swapInterval;
-	EGLClientBuffer clientBuffer;
-	EGLint clientBufferPlane;
 };
 
 class WindowSurface : public Surface
@@ -121,7 +130,7 @@
 	bool reset(int backBufferWidth, int backBufferHeight);
 
 	const EGLNativeWindowType window;
-	sw::FrameBuffer *frameBuffer;
+	sw::FrameBuffer *frameBuffer = nullptr;
 };
 
 class PBufferSurface : public Surface
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 74510df..8e0be66 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -392,10 +392,10 @@
 	switch(attribute)
 	{
 	case EGL_VG_ALPHA_FORMAT:
-		UNIMPLEMENTED();   // FIXME
+		*value = EGL_VG_ALPHA_FORMAT_NONPRE;   // Default
 		break;
 	case EGL_VG_COLORSPACE:
-		UNIMPLEMENTED();   // FIXME
+		*value = EGL_VG_COLORSPACE_sRGB;   // Default
 		break;
 	case EGL_CONFIG_ID:
 		*value = eglSurface->getConfigID();
@@ -404,7 +404,7 @@
 		*value = eglSurface->getHeight();
 		break;
 	case EGL_HORIZONTAL_RESOLUTION:
-		UNIMPLEMENTED();   // FIXME
+		*value = EGL_UNKNOWN;
 		break;
 	case EGL_LARGEST_PBUFFER:
 		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
@@ -413,13 +413,19 @@
 		}
 		break;
 	case EGL_MIPMAP_TEXTURE:
-		UNIMPLEMENTED();   // FIXME
+		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
+		{
+			*value = EGL_FALSE;   // UNIMPLEMENTED
+		}
 		break;
 	case EGL_MIPMAP_LEVEL:
-		UNIMPLEMENTED();   // FIXME
+		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
+		{
+			*value = eglSurface->getMipmapLevel();
+		}
 		break;
 	case EGL_MULTISAMPLE_RESOLVE:
-		UNIMPLEMENTED();   // FIXME
+		*value = eglSurface->getMultisampleResolve();
 		break;
 	case EGL_PIXEL_ASPECT_RATIO:
 		*value = eglSurface->getPixelAspectRatio();
@@ -431,13 +437,19 @@
 		*value = eglSurface->getSwapBehavior();
 		break;
 	case EGL_TEXTURE_FORMAT:
-		*value = eglSurface->getTextureFormat();
+		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
+		{
+			*value = eglSurface->getTextureFormat();
+		}
 		break;
 	case EGL_TEXTURE_TARGET:
-		*value = eglSurface->getTextureTarget();
+		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
+		{
+			*value = eglSurface->getTextureTarget();
+		}
 		break;
 	case EGL_VERTICAL_RESOLUTION:
-		UNIMPLEMENTED();   // FIXME
+		*value = EGL_UNKNOWN;
 		break;
 	case EGL_WIDTH:
 		*value = eglSurface->getWidth();
@@ -544,22 +556,43 @@
 
 	switch(attribute)
 	{
-	case EGL_SWAP_BEHAVIOR:
-		if(value == EGL_BUFFER_PRESERVED)
+	case EGL_MIPMAP_LEVEL:
+		eglSurface->setMipmapLevel(value);
+		break;
+	case EGL_MULTISAMPLE_RESOLVE:
+		switch(value)
 		{
+		case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
+			break;
+		case EGL_MULTISAMPLE_RESOLVE_BOX:
+			if(!(eglSurface->getSurfaceType() & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
+			{
+				return error(EGL_BAD_MATCH, EGL_FALSE);
+			}
+			break;
+		default:
+			return error(EGL_BAD_PARAMETER, EGL_FALSE);
+		}
+		eglSurface->setMultisampleResolve(value);
+		break;
+	case EGL_SWAP_BEHAVIOR:
+		switch(value)
+		{
+		case EGL_BUFFER_DESTROYED:
+			break;
+		case EGL_BUFFER_PRESERVED:
 			if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
 			{
 				return error(EGL_BAD_MATCH, EGL_FALSE);
 			}
-		}
-		else if(value != EGL_BUFFER_DESTROYED)
-		{
+			break;
+		default:
 			return error(EGL_BAD_PARAMETER, EGL_FALSE);
 		}
 		eglSurface->setSwapBehavior(value);
 		break;
 	default:
-		UNIMPLEMENTED();   // FIXME
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
 	}
 
 	return success(EGL_TRUE);