Fix draw buffers support.

Bug 19353282

Change-Id: I6d1022c42a3347b8deb01af15078769d794050cb
Reviewed-on: https://swiftshader-review.googlesource.com/5146
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/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index af7a884..e20f275 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -733,10 +733,11 @@
 

 void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)

 {

-	Framebuffer* drawFramebuffer = getDrawFramebuffer();

-	for(int i = 0; i < n; ++i)

+	Framebuffer *drawFramebuffer = getDrawFramebuffer();

+

+	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)

 	{

-		drawFramebuffer->setDrawBuffer(i, bufs[i]);

+		drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);

 	}

 }

 

@@ -2082,8 +2083,8 @@
 			return false;

 		}

 		break;

-	case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK​

-	case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE

+	case GL_DRAW_BUFFER0:

+	case GL_DRAW_BUFFER1:

 	case GL_DRAW_BUFFER2:

 	case GL_DRAW_BUFFER3:

 	case GL_DRAW_BUFFER4:

@@ -2100,7 +2101,7 @@
 	case GL_DRAW_BUFFER15:

 		*params = getDrawFramebuffer()->getDrawBuffer(pname - GL_DRAW_BUFFER0);

 		break;

-	case GL_MAJOR_VERSION: // integer, at least 3

+	case GL_MAJOR_VERSION:

 		if(clientVersion >= 3)

 		{

 			*params = clientVersion;

@@ -2116,7 +2117,7 @@
 	case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048

 		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;

 		break;

-	case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8

+	case GL_MAX_COLOR_ATTACHMENTS:

 		*params = MAX_COLOR_ATTACHMENTS;

 		break;

 	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048

@@ -2129,8 +2130,7 @@
 	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176

 		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;

 		break;

-	case GL_MAX_DRAW_BUFFERS: // integer, at least 8

-		UNIMPLEMENTED();

+	case GL_MAX_DRAW_BUFFERS:

 		*params = MAX_DRAW_BUFFERS;

 		break;

 	case GL_MAX_ELEMENT_INDEX:

@@ -2676,11 +2676,18 @@
         return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);

     }

 

-	for(int i = 0; i < MAX_DRAW_BUFFERS; ++i)

+	for(int i = 0; i < MAX_DRAW_BUFFERS; i++)

 	{

-		egl::Image *renderTarget = framebuffer->getRenderTarget(i);

-		device->setRenderTarget(i, renderTarget);

-		if(renderTarget) renderTarget->release();

+		if(framebuffer->getDrawBuffer(i) != GL_NONE)

+		{

+			egl::Image *renderTarget = framebuffer->getRenderTarget(i);

+			device->setRenderTarget(i, renderTarget);

+			if(renderTarget) renderTarget->release();

+		}

+		else

+		{

+			device->setRenderTarget(i, nullptr);

+		}

 	}

 

     egl::Image *depthBuffer = framebuffer->getDepthBuffer();

@@ -2840,7 +2847,11 @@
 

     if(mMaskStateDirty)

     {

-		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));

+		for(int i = 0; i < MAX_DRAW_BUFFERS; i++)

+		{

+			device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));

+		}

+

 		device->setDepthWriteEnable(mState.depthMask);

 

         mMaskStateDirty = false;

diff --git a/src/OpenGL/libGLESv2/Framebuffer.cpp b/src/OpenGL/libGLESv2/Framebuffer.cpp
index 34f3263..dd19870 100644
--- a/src/OpenGL/libGLESv2/Framebuffer.cpp
+++ b/src/OpenGL/libGLESv2/Framebuffer.cpp
@@ -80,11 +80,6 @@
 {
 	mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
 	mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer);
-	drawBuffer[index] = (colorbuffer != 0) ? GL_COLOR_ATTACHMENT0 + index : GL_NONE;
-	if(index == 0)
-	{
-		readBuffer = drawBuffer[0];
-	}
 }
 
 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 1adb45c..419d091 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1137,11 +1137,6 @@
 		return error(GL_INVALID_VALUE);

 	}

 

-	if(n == 0)

-	{

-		return;

-	}

-

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

 

 	if(context)

@@ -1197,21 +1192,24 @@
 			case GL_COLOR_ATTACHMENT29:

 			case GL_COLOR_ATTACHMENT30:

 			case GL_COLOR_ATTACHMENT31:

-			{

-				GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0);

-				if(index >= MAX_COLOR_ATTACHMENTS)

 				{

-					return error(GL_INVALID_ENUM);

+					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0);

+

+					if(index >= MAX_COLOR_ATTACHMENTS)

+					{

+						return error(GL_INVALID_OPERATION);

+					}

+

+					if(index != i)

+					{

+						return error(GL_INVALID_OPERATION);

+					}

+

+					if(drawFramebufferName == 0)

+					{

+						return error(GL_INVALID_OPERATION);

+					}

 				}

-				if(index != i)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				if(drawFramebufferName == 0)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-			}

 				break;

 			default:

 				return error(GL_INVALID_ENUM);