Added more GLES 3.0 specific cases in GetFramebufferAttachmentParameteriv

These new entries will need to be updated once more internal
formats are available, but this will do for now.

Also added the possibility to query the Framebuffer 0 for GL_BACK,
GL_DEPTH and GL_STENCIL, as is allowed by OpenGL ES 3.0.

Finally, added a missing break in the GL_DEPTH_STENCIL_ATTACHMENT case.

Change-Id: Ifc32cc306c762ff58f9a9fe6608f7c19d3901c31
Reviewed-on: https://swiftshader-review.googlesource.com/3632
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index e1ffae8..dd6e3dc 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -2922,12 +2922,26 @@
 			return error(GL_INVALID_ENUM);

 		}

 

+		egl::GLint clientVersion = context->getClientVersion();

+

 		es2::Framebuffer *framebuffer = NULL;

 		if(target == GL_READ_FRAMEBUFFER_ANGLE)

 		{

 			if(context->getReadFramebufferName() == 0)

 			{

-				return error(GL_INVALID_OPERATION);

+				switch(attachment)

+				{

+				case GL_BACK:

+				case GL_DEPTH:

+				case GL_STENCIL:

+					if(clientVersion >= 3)

+					{

+						break;

+					}

+					// fall through

+				default:

+					return error(GL_INVALID_OPERATION);

+				}

 			}

 

 			framebuffer = context->getReadFramebuffer();

@@ -2936,18 +2950,38 @@
 		{

 			if(context->getDrawFramebufferName() == 0)

 			{

-				return error(GL_INVALID_OPERATION);

+				switch(attachment)

+				{

+				case GL_BACK:

+				case GL_DEPTH:

+				case GL_STENCIL:

+					if(clientVersion >= 3)

+					{

+						break;

+					}

+					// fall through

+				default:

+					return error(GL_INVALID_OPERATION);

+				}

 			}

 

 			framebuffer = context->getDrawFramebuffer();

 		}

 

-		egl::GLint clientVersion = context->getClientVersion();

-

 		GLenum attachmentType;

 		GLuint attachmentHandle;

+		Renderbuffer* renderbuffer = nullptr;

 		switch(attachment)

 		{

+		case GL_BACK:

+			if(clientVersion >= 3)

+			{

+				attachmentType = framebuffer->getColorbufferType(0);

+				attachmentHandle = framebuffer->getColorbufferName(0);

+				renderbuffer = framebuffer->getColorbuffer(0);

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

 		case GL_COLOR_ATTACHMENT1:

 		case GL_COLOR_ATTACHMENT2:

 		case GL_COLOR_ATTACHMENT3:

@@ -2975,14 +3009,29 @@
 			}

 			attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);

 			attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);

+			renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);

 			break;

+		case GL_DEPTH:

+			if(clientVersion < 3)

+			{

+				return error(GL_INVALID_ENUM);

+			}

+			// fall through

 		case GL_DEPTH_ATTACHMENT:

 			attachmentType = framebuffer->getDepthbufferType();

 			attachmentHandle = framebuffer->getDepthbufferName();

+			renderbuffer = framebuffer->getDepthbuffer();

 			break;

+		case GL_STENCIL:

+			if(clientVersion < 3)

+			{

+				return error(GL_INVALID_ENUM);

+			}

+			// fall through

 		case GL_STENCIL_ATTACHMENT:

 			attachmentType = framebuffer->getStencilbufferType();

 			attachmentHandle = framebuffer->getStencilbufferName();

+			renderbuffer = framebuffer->getStencilbuffer();

 			break;

 		case GL_DEPTH_STENCIL_ATTACHMENT:

 			if(clientVersion >= 3)

@@ -2994,8 +3043,10 @@
 					// Different attachments to DEPTH and STENCIL, query fails

 					return error(GL_INVALID_OPERATION);

 				}

+				renderbuffer = framebuffer->getDepthbuffer();

 			}

 			else return error(GL_INVALID_ENUM);

+			break;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

@@ -3053,6 +3104,67 @@
 				return error(GL_INVALID_ENUM);

 			}

 			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:

+			if(clientVersion >= 3)

+			{

+				*params = renderbuffer->getRedSize();

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:

+			if(clientVersion >= 3)

+			{

+				*params = renderbuffer->getGreenSize();

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:

+			if(clientVersion >= 3)

+			{

+				*params = renderbuffer->getBlueSize();

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:

+			if(clientVersion >= 3)

+			{

+				*params = renderbuffer->getAlphaSize();

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:

+			if(clientVersion >= 3)

+			{

+				*params = renderbuffer->getDepthSize();

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:

+			if(clientVersion >= 3)

+			{

+				*params = renderbuffer->getStencilSize();

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:

+			if(clientVersion >= 3)

+			{

+				if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)

+				{

+					return error(GL_INVALID_OPERATION);

+				}

+

+				*params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

+		case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:

+			if(clientVersion >= 3)

+			{

+				*params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added

+			}

+			else return error(GL_INVALID_ENUM);

+			break;

 		default:

 			return error(GL_INVALID_ENUM);

 		}

diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index a60efea..001e88d 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -907,6 +907,54 @@
 		}

 	}

 

+	GLenum GetComponentType(sw::Format format, GLenum attachment)

+	{

+		// Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED

+		switch(attachment)

+		{

+		case GL_COLOR_ATTACHMENT0:

+		case GL_COLOR_ATTACHMENT1:

+		case GL_COLOR_ATTACHMENT2:

+		case GL_COLOR_ATTACHMENT3:

+		case GL_COLOR_ATTACHMENT4:

+		case GL_COLOR_ATTACHMENT5:

+		case GL_COLOR_ATTACHMENT6:

+		case GL_COLOR_ATTACHMENT7:

+		case GL_COLOR_ATTACHMENT8:

+		case GL_COLOR_ATTACHMENT9:

+		case GL_COLOR_ATTACHMENT10:

+		case GL_COLOR_ATTACHMENT11:

+		case GL_COLOR_ATTACHMENT12:

+		case GL_COLOR_ATTACHMENT13:

+		case GL_COLOR_ATTACHMENT14:

+		case GL_COLOR_ATTACHMENT15:

+			switch(format)

+			{

+			case sw::FORMAT_A16B16G16R16F:

+			case sw::FORMAT_A32B32G32R32F:

+				return GL_FLOAT;

+			case sw::FORMAT_A2R10G10B10:

+			case sw::FORMAT_A8R8G8B8:

+			case sw::FORMAT_A8B8G8R8:

+			case sw::FORMAT_X8R8G8B8:

+			case sw::FORMAT_X8B8G8R8:

+			case sw::FORMAT_A1R5G5B5:

+			case sw::FORMAT_R5G6B5:

+				return GL_UNSIGNED_NORMALIZED;

+			default:

+				UNREACHABLE(format);

+				return 0;

+			}

+		case GL_DEPTH_ATTACHMENT:

+		case GL_STENCIL_ATTACHMENT:

+			// Only color buffers may have integer components.

+			return GL_FLOAT;

+		default:

+			UNREACHABLE(attachment);

+			return 0;

+		}

+	}

+

 	GLenum ConvertBackBufferFormat(sw::Format format)

 	{

 		switch(format)

diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index 7e3ce06..49ba9cb 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -79,6 +79,7 @@
 	GLuint GetBlueSize(sw::Format colorFormat);

 	GLuint GetDepthSize(sw::Format depthFormat);

 	GLuint GetStencilSize(sw::Format stencilFormat);

+	GLenum GetComponentType(sw::Format format, GLenum attachment);

 

 	GLenum ConvertBackBufferFormat(sw::Format format);

 	GLenum ConvertDepthStencilFormat(sw::Format format);