Added Functions for gathering all referenced D3D and DXGI formats. Renderers now use these functions to generate the multisample support maps.

TRAC #23212

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index bcdd349..a96ecd5 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -273,38 +273,15 @@
     }
 #endif
 
-    unsigned int maxSupportedSamples = 0;
-    unsigned int rtFormatCount = ArraySize(RenderTargetFormats);
-    unsigned int dsFormatCount = ArraySize(DepthStencilFormats);
-    for (unsigned int i = 0; i < rtFormatCount + dsFormatCount; ++i)
+    mMaxSupportedSamples = 0;
+
+    const d3d11::DXGIFormatSet &dxgiFormats = d3d11::GetAllUsedDXGIFormats();
+    for (d3d11::DXGIFormatSet::const_iterator i = dxgiFormats.begin(); i != dxgiFormats.end(); ++i)
     {
-        DXGI_FORMAT format = (i < rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount];
-        if (format != DXGI_FORMAT_UNKNOWN)
-        {
-            UINT formatSupport;
-            result = mDevice->CheckFormatSupport(format, &formatSupport);
-            if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
-            {
-                MultisampleSupportInfo supportInfo;
-
-                for (unsigned int j = 1; j <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++)
-                {
-                    result = mDevice->CheckMultisampleQualityLevels(format, j, &supportInfo.qualityLevels[j - 1]);
-                    if (SUCCEEDED(result) && supportInfo.qualityLevels[j - 1] > 0)
-                    {
-                        maxSupportedSamples = std::max(j, maxSupportedSamples);
-                    }
-                    else
-                    {
-                        supportInfo.qualityLevels[j - 1] = 0;
-                    }
-                }
-
-                mMultisampleSupportMap.insert(std::make_pair(format, supportInfo));
-            }
-        }
+        MultisampleSupportInfo support = getMultisampleSupportInfo(*i);
+        mMultisampleSupportMap.insert(std::make_pair(*i, support));
+        mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples);
     }
-    mMaxSupportedSamples = maxSupportedSamples;
 
     initializeDevice();
 
@@ -4004,4 +3981,31 @@
     return true;
 }
 
+Renderer11::MultisampleSupportInfo Renderer11::getMultisampleSupportInfo(DXGI_FORMAT format)
+{
+    MultisampleSupportInfo supportInfo = { 0 };
+
+    UINT formatSupport;
+    HRESULT result;
+
+    result = mDevice->CheckFormatSupport(format, &formatSupport);
+    if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
+    {
+        for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
+        {
+            result = mDevice->CheckMultisampleQualityLevels(format, i, &supportInfo.qualityLevels[i - 1]);
+            if (SUCCEEDED(result) && supportInfo.qualityLevels[i - 1] > 0)
+            {
+                supportInfo.maxSupportedSamples = std::max(supportInfo.maxSupportedSamples, i);
+            }
+            else
+            {
+                supportInfo.qualityLevels[i - 1] = 0;
+            }
+        }
+    }
+
+    return supportInfo;
+}
+
 }
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 3e8b456..399ff6a 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -256,7 +256,9 @@
     struct MultisampleSupportInfo
     {
         unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT];
+        unsigned int maxSupportedSamples;
     };
+    MultisampleSupportInfo getMultisampleSupportInfo(DXGI_FORMAT format);
 
     typedef std::unordered_map<DXGI_FORMAT, MultisampleSupportInfo> MultisampleSupportMap;
     MultisampleSupportMap mMultisampleSupportMap;
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index af38a66..02efc69 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -169,12 +169,6 @@
     {
         mD3d9Module = NULL;
     }
-
-    while (!mMultiSampleSupport.empty())
-    {
-        delete [] mMultiSampleSupport.begin()->second;
-        mMultiSampleSupport.erase(mMultiSampleSupport.begin());
-    }
 }
 
 Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
@@ -308,42 +302,16 @@
         mMaxSwapInterval = std::max(mMaxSwapInterval, 4);
     }
 
-    int max = 0;
-    for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i)
+    mMaxSupportedSamples = 0;
+
+    const d3d9::D3DFormatSet &d3d9Formats = d3d9::GetAllUsedD3DFormats();
+    for (d3d9::D3DFormatSet::const_iterator i = d3d9Formats.begin(); i != d3d9Formats.end(); ++i)
     {
-        bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
-        getMultiSampleSupport(RenderTargetFormats[i], multisampleArray);
-        mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray;
-
-        for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
-        {
-            if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
-            {
-                max = j;
-            }
-        }
+        MultisampleSupportInfo support = getMultiSampleSupport(*i);
+        mMultiSampleSupport[*i] = support;
+        mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples);
     }
 
-    for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i)
-    {
-        if (DepthStencilFormats[i] == D3DFMT_UNKNOWN)
-            continue;
-
-        bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
-        getMultiSampleSupport(DepthStencilFormats[i], multisampleArray);
-        mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray;
-
-        for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
-        {
-            if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
-            {
-                max = j;
-            }
-        }
-    }
-
-    mMaxSupportedSamples = max;
-
     static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
     static const TCHAR className[] = TEXT("STATIC");
 
@@ -2193,15 +2161,30 @@
     return mAdapterIdentifier.DeviceIdentifier;
 }
 
-void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
+Renderer9::MultisampleSupportInfo Renderer9::getMultiSampleSupport(D3DFORMAT format)
 {
-    for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
-    {
-        HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
-                                                           TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
+    MultisampleSupportInfo support = { 0 };
 
-        multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
+    for (unsigned int multiSampleIndex = 0; multiSampleIndex < ArraySize(support.supportedSamples); multiSampleIndex++)
+    {
+        HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, TRUE,
+                                                           (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
+
+        if (SUCCEEDED(result))
+        {
+             support.supportedSamples[multiSampleIndex] = true;
+             if (multiSampleIndex != D3DMULTISAMPLE_NONMASKABLE)
+             {
+                 support.maxSupportedSamples = std::max(support.maxSupportedSamples, multiSampleIndex);
+             }
+        }
+        else
+        {
+            support.supportedSamples[multiSampleIndex] = false;
+        }
     }
+
+    return support;
 }
 
 bool Renderer9::getBGRATextureSupport() const
@@ -2460,7 +2443,7 @@
         return requested;
     }
 
-    std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
+    MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format);
     if (itr == mMultiSampleSupport.end())
     {
         if (format == D3DFMT_UNKNOWN)
@@ -2468,9 +2451,9 @@
         return -1;
     }
 
-    for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
+    for (unsigned int i = requested; i < ArraySize(itr->second.supportedSamples); ++i)
     {
-        if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
+        if (itr->second.supportedSamples[i] && i != D3DMULTISAMPLE_NONMASKABLE)
         {
             return i;
         }
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index 16911df..a0d9fa7 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -227,7 +227,6 @@
     void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
     void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer);
 
-    void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
     bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
     gl::Renderbuffer *getNullColorbuffer(gl::Renderbuffer *depthbuffer);
 
@@ -287,8 +286,16 @@
     bool mLuminanceTextureSupport;
     bool mLuminanceAlphaTextureSupport;
 
-    std::map<D3DFORMAT, bool *> mMultiSampleSupport;
-    GLsizei mMaxSupportedSamples;
+    struct MultisampleSupportInfo
+    {
+        bool supportedSamples[D3DMULTISAMPLE_16_SAMPLES + 1];
+        unsigned int maxSupportedSamples;
+    };
+    typedef std::map<D3DFORMAT, MultisampleSupportInfo> MultisampleSupportMap;
+    MultisampleSupportMap mMultiSampleSupport;
+    unsigned int mMaxSupportedSamples;
+
+    MultisampleSupportInfo getMultiSampleSupport(D3DFORMAT format);
 
     // current render target states
     unsigned int mAppliedRenderTargetSerial;
diff --git a/src/libGLESv2/renderer/formatutils11.cpp b/src/libGLESv2/renderer/formatutils11.cpp
index 3251813..a224e46 100644
--- a/src/libGLESv2/renderer/formatutils11.cpp
+++ b/src/libGLESv2/renderer/formatutils11.cpp
@@ -512,9 +512,15 @@
     return map;
 }
 
-static bool getDXGIFormatInfo(DXGI_FORMAT format, DXGIFormatInfo *outFormatInfo)
+static const DXGIFormatInfoMap &GetDXGIFormatInfoMap()
 {
     static const DXGIFormatInfoMap infoMap = buildDXGIFormatInfoMap();
+    return infoMap;
+}
+
+static bool getDXGIFormatInfo(DXGI_FORMAT format, DXGIFormatInfo *outFormatInfo)
+{
+    const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap();
     DXGIFormatInfoMap::const_iterator iter = infoMap.find(format);
     if (iter != infoMap.end())
     {
@@ -530,6 +536,19 @@
     }
 }
 
+static d3d11::DXGIFormatSet BuildAllDXGIFormatSet()
+{
+    d3d11::DXGIFormatSet set;
+
+    const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap();
+    for (DXGIFormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i)
+    {
+        set.insert(i->first);
+    }
+
+    return set;
+}
+
 namespace d3d11
 {
 
@@ -653,6 +672,12 @@
     }
 }
 
+const DXGIFormatSet &GetAllUsedDXGIFormats()
+{
+    static DXGIFormatSet formatSet = BuildAllDXGIFormatSet();
+    return formatSet;
+}
+
 }
 
 namespace gl_d3d11
diff --git a/src/libGLESv2/renderer/formatutils11.h b/src/libGLESv2/renderer/formatutils11.h
index 06abc4a..454b909 100644
--- a/src/libGLESv2/renderer/formatutils11.h
+++ b/src/libGLESv2/renderer/formatutils11.h
@@ -18,6 +18,8 @@
 namespace d3d11
 {
 
+typedef std::set<DXGI_FORMAT> DXGIFormatSet;
+
 MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format);
 LoadImageFunction GetImageLoadFunction(GLint internalFormat, GLenum type, GLuint clientVersion);
 
@@ -27,6 +29,8 @@
 
 void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
 
+const DXGIFormatSet &GetAllUsedDXGIFormats();
+
 }
 
 namespace gl_d3d11
diff --git a/src/libGLESv2/renderer/formatutils9.cpp b/src/libGLESv2/renderer/formatutils9.cpp
index a0321d3..a2bba1a 100644
--- a/src/libGLESv2/renderer/formatutils9.cpp
+++ b/src/libGLESv2/renderer/formatutils9.cpp
@@ -209,9 +209,15 @@
     return map;
 }
 
-static bool getD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo)
+static const D3D9FormatInfoMap &GetD3D9FormatInfoMap()
 {
     static const D3D9FormatInfoMap infoMap = buildD3D9FormatInfoMap();
+    return infoMap;
+}
+
+static bool getD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo)
+{
+    const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
     D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
     if (iter != infoMap.end())
     {
@@ -226,6 +232,18 @@
         return false;
     }
 }
+static d3d9::D3DFormatSet BuildAllD3DFormatSet()
+{
+    d3d9::D3DFormatSet set;
+
+    const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
+    for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i)
+    {
+        set.insert(i->first);
+    }
+
+    return set;
+}
 
 namespace d3d9
 {
@@ -348,6 +366,12 @@
     }
 }
 
+const D3DFormatSet &GetAllUsedD3DFormats()
+{
+    static const D3DFormatSet formatSet = BuildAllD3DFormatSet();
+    return formatSet;
+}
+
 }
 
 namespace gl_d3d9
diff --git a/src/libGLESv2/renderer/formatutils9.h b/src/libGLESv2/renderer/formatutils9.h
index 5248bc6..3e6fb4b 100644
--- a/src/libGLESv2/renderer/formatutils9.h
+++ b/src/libGLESv2/renderer/formatutils9.h
@@ -20,6 +20,8 @@
 namespace d3d9
 {
 
+typedef std::set<D3DFORMAT> D3DFormatSet;
+
 MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format);
 LoadImageFunction GetImageLoadFunction(GLint internalFormat, const Renderer9 *renderer);
 
@@ -30,6 +32,8 @@
 
 void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
 
+const D3DFormatSet &GetAllUsedD3DFormats();
+
 }
 
 namespace gl_d3d9