Implements queriability for internal format sample counts.

TRAC #23273

Authored-by: Shannon Woods
Signed-off-by: Geoff Lang
Signed-off-by: Nicolas Capens
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 5d7389a..871e566 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -2550,6 +2550,16 @@
     return mRenderer->getMaxSupportedFormatSamples(internalFormat);
 }
 
+GLsizei Context::getNumSampleCounts(GLint internalFormat) const
+{
+    return mRenderer->getNumSampleCounts(internalFormat);
+}
+
+void Context::getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const
+{
+    mRenderer->getSampleCounts(internalFormat, bufSize, params);
+}
+
 unsigned int Context::getMaxTransformFeedbackBufferBindings() const
 {
     return mRenderer->getMaxTransformFeedbackBuffers();
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index bfff910..ece4fbf 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -373,6 +373,8 @@
     unsigned int getMaximumRenderTargets() const;
     GLsizei getMaxSupportedSamples() const;
     GLsizei getMaxSupportedFormatSamples(GLint internalFormat) const;
+    GLsizei getNumSampleCounts(GLint internalFormat) const;
+    void getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const;
     unsigned int getMaxTransformFeedbackBufferBindings() const;
     GLintptr getUniformBufferOffsetAlignment() const;
     const char *getCombinedExtensionsString() const;
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 8836d56..41b28d5 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -204,6 +204,8 @@
 
     virtual GLsizei getMaxSupportedSamples() const = 0;
     virtual GLsizei getMaxSupportedFormatSamples(GLint internalFormat) const = 0;
+    virtual GLsizei getNumSampleCounts(GLint internalFormat) const = 0;
+    virtual void getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const = 0;
 
     virtual unsigned int getMaxRenderTargets() const = 0;
 
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 6401dde..a1a0dc3 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -2456,6 +2456,55 @@
     return (iter != mMultisampleSupportMap.end()) ? iter->second.maxSupportedSamples : 0;
 }
 
+GLsizei Renderer11::getNumSampleCounts(GLint internalFormat) const
+{
+    unsigned int numCounts = 0;
+
+    // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
+    if (!gl::IsIntegerFormat(internalFormat, getCurrentClientVersion()))
+    {
+        DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
+        MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
+
+        if (iter != mMultisampleSupportMap.end())
+        {
+            const MultisampleSupportInfo& info = iter->second;
+            for (int i = 0; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
+            {
+                if (info.qualityLevels[i] > 0)
+                {
+                    numCounts++;
+                }
+            }
+        }
+    }
+
+    return numCounts;
+}
+
+void Renderer11::getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const
+{
+    // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
+    if (gl::IsIntegerFormat(internalFormat, getCurrentClientVersion()))
+        return;
+
+    DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
+    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
+
+    if (iter != mMultisampleSupportMap.end())
+    {
+        const MultisampleSupportInfo& info = iter->second;
+        int bufPos = 0;
+        for (int i = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i >= 0 && bufPos < bufSize; i--)
+        {
+            if (info.qualityLevels[i] > 0)
+            {
+                params[bufPos++] = i + 1;
+            }
+        }
+    }
+}
+
 int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
 {
     if (requested == 0)
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 10af628..8276654 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -146,6 +146,8 @@
 
     virtual GLsizei getMaxSupportedSamples() const;
     virtual GLsizei getMaxSupportedFormatSamples(GLint internalFormat) const;
+    virtual GLsizei getNumSampleCounts(GLint internalFormat) const;
+    virtual void getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const;
     int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const;
 
     virtual unsigned int getMaxRenderTargets() const;
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index c6f9bef..ddcb5a1 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -2455,6 +2455,46 @@
     return (itr != mMultiSampleSupport.end()) ? mMaxSupportedSamples : 0;
 }
 
+GLsizei Renderer9::getNumSampleCounts(GLint internalFormat) const
+{
+    D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this);
+    MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format);
+    
+    unsigned int numCounts = 0;
+    if (iter != mMultiSampleSupport.end())
+    {
+        const MultisampleSupportInfo& info = iter->second;
+        for (int i = 0; i < D3DMULTISAMPLE_16_SAMPLES; i++)
+        {
+            if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i])
+            {
+                numCounts++;
+            }
+        }
+    }
+
+    return numCounts;
+}
+
+void Renderer9::getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const
+{
+    D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this);
+    MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format);
+
+    if (iter != mMultiSampleSupport.end())
+    {
+        const MultisampleSupportInfo& info = iter->second;
+        int bufPos = 0;
+        for (int i = D3DMULTISAMPLE_16_SAMPLES; i >= 0 && bufPos < bufSize; i--)
+        {
+            if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i])
+            {
+                params[bufPos++] = i;
+            }
+        }
+    }
+}
+
 int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const
 {
     if (requested == 0)
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index d758972..64d23bb 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -162,6 +162,8 @@
 
     virtual GLsizei getMaxSupportedSamples() const;
     virtual GLsizei getMaxSupportedFormatSamples(GLint internalFormat) const;
+    virtual GLsizei getNumSampleCounts(GLint internalFormat) const;
+    virtual void getSampleCounts(GLint internalFormat, GLsizei bufSize, GLint *params) const;
     int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
     
     virtual unsigned int getMaxRenderTargets() const;