Vulkan: prepare for ES3

This makes ES3_VULKAN() pass the instantiability test, allowing it to be
specified in end2end tests.

Bug: angleproject:2950
Change-Id: Ife70a22fb8193f9eebe64bec491a24b47bc76939
Reviewed-on: https://chromium-review.googlesource.com/c/1325729
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.cpp b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
index 43ce101..f41ec3b 100644
--- a/src/libANGLE/renderer/vulkan/DisplayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
@@ -159,8 +159,7 @@
 
 gl::Version DisplayVk::getMaxSupportedESVersion() const
 {
-    UNIMPLEMENTED();
-    return gl::Version(0, 0);
+    return mRenderer->getMaxSupportedESVersion();
 }
 
 void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 47b01e5..dba99da 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -531,8 +531,8 @@
     GlslangWrapper::Initialize();
 
     // Initialize the format table.
-    mFormatTable.initialize(mPhysicalDevice, mFeatures, &mNativeTextureCaps,
-                            &mNativeCaps.compressedTextureFormats);
+    mFormatTable.initialize(mPhysicalDevice, mPhysicalDeviceProperties, mFeatures,
+                            &mNativeTextureCaps, &mNativeCaps.compressedTextureFormats);
 
     return angle::Result::Continue();
 }
@@ -733,6 +733,19 @@
     return strstr.str();
 }
 
+gl::Version RendererVk::getMaxSupportedESVersion() const
+{
+    // Declare GLES2 support if necessary features for GLES3 are missing
+    bool necessaryFeaturesForES3 = mPhysicalDeviceFeatures.inheritedQueries;
+
+    if (!necessaryFeaturesForES3)
+    {
+        return gl::Version(2, 0);
+    }
+
+    return gl::Version(3, 0);
+}
+
 void RendererVk::initFeatures()
 {
 // Use OpenGL line rasterization rules by default.
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.h b/src/libANGLE/renderer/vulkan/RendererVk.h
index 7efa489..df9b95e 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.h
+++ b/src/libANGLE/renderer/vulkan/RendererVk.h
@@ -55,6 +55,8 @@
     std::string getVendorString() const;
     std::string getRendererDescription() const;
 
+    gl::Version getMaxSupportedESVersion() const;
+
     VkInstance getInstance() const { return mInstance; }
     VkPhysicalDevice getPhysicalDevice() const { return mPhysicalDevice; }
     const VkPhysicalDeviceProperties &getPhysicalDeviceProperties() const
diff --git a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
index 01ff385..36c8a06 100644
--- a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
@@ -200,11 +200,18 @@
 
 // Generates a basic config for a combination of color format, depth stencil format and sample
 // count.
-egl::Config GenerateDefaultConfig(const VkPhysicalDeviceProperties &physicalDeviceProperties,
+egl::Config GenerateDefaultConfig(const RendererVk *renderer,
                                   const gl::InternalFormat &colorFormat,
                                   const gl::InternalFormat &depthStencilFormat,
                                   EGLint sampleCount)
 {
+    const VkPhysicalDeviceProperties &physicalDeviceProperties =
+        renderer->getPhysicalDeviceProperties();
+    gl::Version maxSupportedESVersion = renderer->getMaxSupportedESVersion();
+
+    EGLint es2Support = (maxSupportedESVersion.major >= 2 ? EGL_OPENGL_ES2_BIT : 0);
+    EGLint es3Support = (maxSupportedESVersion.major >= 3 ? EGL_OPENGL_ES3_BIT : 0);
+
     egl::Config config;
 
     config.renderTargetFormat    = colorFormat.internalFormat;
@@ -232,7 +239,7 @@
     config.nativeRenderable      = EGL_TRUE;
     config.nativeVisualID        = 0;
     config.nativeVisualType      = EGL_NONE;
-    config.renderableType        = EGL_OPENGL_ES2_BIT;
+    config.renderableType        = es2Support | es3Support;
     config.sampleBuffers         = (sampleCount > 0) ? 1 : 0;
     config.samples               = sampleCount;
     config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
@@ -264,10 +271,6 @@
 
     egl::ConfigSet configSet;
 
-    const RendererVk *renderer = display->getRenderer();
-    const VkPhysicalDeviceProperties &physicalDeviceProperties =
-        renderer->getPhysicalDeviceProperties();
-
     for (size_t colorFormatIdx = 0; colorFormatIdx < colorFormatsCount; colorFormatIdx++)
     {
         const gl::InternalFormat &colorFormatInfo =
@@ -286,7 +289,7 @@
                  sampleCountIndex++)
             {
                 egl::Config config =
-                    GenerateDefaultConfig(physicalDeviceProperties, colorFormatInfo,
+                    GenerateDefaultConfig(display->getRenderer(), colorFormatInfo,
                                           depthStencilFormatInfo, sampleCounts[sampleCountIndex]);
                 if (display->checkConfigSupport(&config))
                 {
diff --git a/src/libANGLE/renderer/vulkan/vk_format_utils.cpp b/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
index 17c5fc7..bd0ec3d 100644
--- a/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
@@ -29,7 +29,21 @@
     return IsMaskFlagSet(formatProperties.optimalTilingFeatures, featureBits);
 }
 
-void FillTextureFormatCaps(const VkFormatProperties &formatProperties,
+void AddSampleCounts(VkSampleCountFlags sampleCounts, gl::SupportedSampleSet *outSet)
+{
+    // The possible bits are VK_SAMPLE_COUNT_n_BIT = n, with n = 1 << b.  At the time of this
+    // writing, b is in [0, 6], however, we test all 32 bits in case the enum is extended.
+    for (unsigned int i = 0; i < 32; ++i)
+    {
+        if ((sampleCounts & (1 << i)) != 0)
+        {
+            outSet->insert(1 << i);
+        }
+    }
+}
+
+void FillTextureFormatCaps(const VkPhysicalDeviceLimits &physicalDeviceLimits,
+                           const VkFormatProperties &formatProperties,
                            gl::TextureCaps *outTextureCaps)
 {
     outTextureCaps->texturable =
@@ -40,6 +54,22 @@
         HasFormatFeatureBits(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, formatProperties) ||
         HasFormatFeatureBits(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, formatProperties);
     outTextureCaps->renderbuffer = outTextureCaps->textureAttachment;
+
+    if (outTextureCaps->renderbuffer)
+    {
+        if (HasFormatFeatureBits(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, formatProperties))
+        {
+            AddSampleCounts(physicalDeviceLimits.framebufferColorSampleCounts,
+                            &outTextureCaps->sampleCounts);
+        }
+        if (HasFormatFeatureBits(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, formatProperties))
+        {
+            AddSampleCounts(physicalDeviceLimits.framebufferDepthSampleCounts,
+                            &outTextureCaps->sampleCounts);
+            AddSampleCounts(physicalDeviceLimits.framebufferStencilSampleCounts,
+                            &outTextureCaps->sampleCounts);
+        }
+    }
 }
 
 bool HasFullTextureFormatSupport(VkPhysicalDevice physicalDevice, VkFormat vkFormat)
@@ -191,6 +221,7 @@
 }
 
 void FormatTable::initialize(VkPhysicalDevice physicalDevice,
+                             const VkPhysicalDeviceProperties &physicalDeviceProperties,
                              const angle::FeaturesVk &featuresVk,
                              gl::TextureCapsMap *outTextureCapsMap,
                              std::vector<GLenum> *outCompressedTextureFormats)
@@ -217,7 +248,7 @@
         VkFormatProperties formatProperties;
         GetFormatProperties(physicalDevice, vkFormat, &formatProperties);
         gl::TextureCaps textureCaps;
-        FillTextureFormatCaps(formatProperties, &textureCaps);
+        FillTextureFormatCaps(physicalDeviceProperties.limits, formatProperties, &textureCaps);
         outTextureCapsMap->set(formatID, textureCaps);
 
         if (angleFormat.isBlock)
diff --git a/src/libANGLE/renderer/vulkan/vk_format_utils.h b/src/libANGLE/renderer/vulkan/vk_format_utils.h
index 4f44a3c..bf4c211 100644
--- a/src/libANGLE/renderer/vulkan/vk_format_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_format_utils.h
@@ -97,6 +97,7 @@
 
     // Also initializes the TextureCapsMap and the compressedTextureCaps in the Caps instance.
     void initialize(VkPhysicalDevice physicalDevice,
+                    const VkPhysicalDeviceProperties &physicalDeviceProperties,
                     const angle::FeaturesVk &featuresVk,
                     gl::TextureCapsMap *outTextureCapsMap,
                     std::vector<GLenum> *outCompressedTextureFormats);