Implements multisample fragment operations
TRAC #12711
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch

Author:    Shannon Woods

git-svn-id: https://angleproject.googlecode.com/svn/trunk@391 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 0f4217d..fe689c1 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1806,7 +1806,7 @@
         mPolygonOffsetStateDirty = false;
     }
 
-    if (mConfig->mMultiSample != 0 && mSampleStateDirty)
+    if (framebufferObject->isMultisample() && mSampleStateDirty)
     {
         if (mState.sampleAlphaToCoverage)
         {
@@ -1815,7 +1815,34 @@
 
         if (mState.sampleCoverage)
         {
-            FIXME("Sample coverage is unimplemented.");
+            device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+            unsigned int mask = 0;
+            if (mState.sampleCoverageValue != 0)
+            {
+                float threshold = 0.5f;
+
+                for (int i = 0; i < framebufferObject->getSamples(); ++i)
+                {
+                    mask <<= 1;
+
+                    if ((i + 1) * mState.sampleCoverageValue >= threshold)
+                    {
+                        threshold += 1.0f;
+                        mask |= 1;
+                    }
+                }
+            }
+            
+            if (mState.sampleCoverageInvert)
+            {
+                mask = ~mask;
+            }
+
+            device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
+        }
+        else
+        {
+            device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
         }
 
         mSampleStateDirty = false;
@@ -2929,6 +2956,7 @@
     mExtensionString += "GL_EXT_read_format_bgra ";
     mExtensionString += "GL_ANGLE_framebuffer_blit ";
 
+
     if (getMaxSupportedSamples() == 0)
     {
         mExtensionString += "GL_ANGLE_framebuffer_multisample ";
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index d030379..2576e40 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -268,6 +268,23 @@
     return false;
 }
 
+bool Framebuffer::isMultisample()
+{
+    // If the framebuffer is not complete, attachment samples may be mismatched, and it
+    // cannot be used as a multisample framebuffer. If it is complete, it is required to
+    // have a color attachment, and all its attachments must have the same number of samples,
+    // so the number of samples for the colorbuffer will indicate whether the framebuffer is
+    // multisampled.
+    if (completeness() == GL_FRAMEBUFFER_COMPLETE && getColorbuffer()->getSamples() > 0)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
 GLenum Framebuffer::completeness()
 {
     int width = 0;
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index cf51658..0995145 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -59,6 +59,7 @@
     GLuint getStencilbufferHandle();
 
     bool hasStencil();
+    bool isMultisample();
     int getSamples();
 
     virtual GLenum completeness();