Have GrVkBackendContext take a VkPhysicalDeviceFeatures struct.

Bug: skia:
Change-Id: Ic7992c89c06789ee631c9f5b4f047c6486e792a5
Reviewed-on: https://skia-review.googlesource.com/137390
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/vk/GrVkBackendContext.h b/include/gpu/vk/GrVkBackendContext.h
index 67ed5f0..e711906 100644
--- a/include/gpu/vk/GrVkBackendContext.h
+++ b/include/gpu/vk/GrVkBackendContext.h
@@ -28,6 +28,7 @@
     kGeometryShader_GrVkFeatureFlag    = 0x0001,
     kDualSrcBlend_GrVkFeatureFlag      = 0x0002,
     kSampleRateShading_GrVkFeatureFlag = 0x0004,
+    kIgnoreAllFlags_GrVkFeatureFlag    = 0x0008,
 };
 
 // The BackendContext contains all of the base Vulkan objects needed by the GrVkGpu. The assumption
@@ -47,7 +48,8 @@
     uint32_t                   fMinAPIVersion;
     uint32_t                   fExtensions = 0;
     const GrVkExtensions*      fVkExtensions = nullptr;
-    uint32_t                   fFeatures = 0;
+    uint32_t                   fFeatures = kIgnoreAllFlags_GrVkFeatureFlag;
+    VkPhysicalDeviceFeatures   fDeviceFeatures;
     sk_sp<GrVkMemoryAllocator> fMemoryAllocator;
     GrVkGetProc                fGetProc = nullptr;
     // This is deprecated and should be set to false. The client is responsible for managing the
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 9f63e36..2bfb11a 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -15,7 +15,7 @@
 #include "vk/GrVkBackendContext.h"
 
 GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
-                   VkPhysicalDevice physDev, uint32_t featureFlags)
+                   VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures& features)
     : INHERITED(contextOptions) {
     fMustDoCopiesFromOrigin = false;
     fMustSubmitCommandsBeforeCopyOp = false;
@@ -47,7 +47,7 @@
 
     fShaderCaps.reset(new GrShaderCaps(contextOptions));
 
-    this->init(contextOptions, vkInterface, physDev, featureFlags);
+    this->init(contextOptions, vkInterface, physDev, features);
 }
 
 bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
@@ -195,7 +195,7 @@
 }
 
 void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
-                    VkPhysicalDevice physDev, uint32_t featureFlags) {
+                    VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures& features) {
 
     VkPhysicalDeviceProperties properties;
     GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
@@ -203,8 +203,8 @@
     VkPhysicalDeviceMemoryProperties memoryProperties;
     GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));
 
-    this->initGrCaps(properties, memoryProperties, featureFlags);
-    this->initShaderCaps(properties, featureFlags);
+    this->initGrCaps(properties, memoryProperties, features);
+    this->initShaderCaps(properties, features);
 
     if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
 #if defined(SK_CPU_X86)
@@ -310,7 +310,7 @@
 
 void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
                           const VkPhysicalDeviceMemoryProperties& memoryProperties,
-                          uint32_t featureFlags) {
+                          const VkPhysicalDeviceFeatures& features) {
     // So GPUs, like AMD, are reporting MAX_INT support vertex attributes. In general, there is no
     // need for us ever to support that amount, and it makes tests which tests all the vertex
     // attribs timeout looping over that many. For now, we'll cap this at 64 max and can raise it if
@@ -339,12 +339,11 @@
     fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
 
     fOversizedStencilSupport = true;
-    fSampleShadingSupport = SkToBool(featureFlags & kSampleRateShading_GrVkFeatureFlag);
-
-
+    fSampleShadingSupport = features.sampleRateShading;
 }
 
-void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint32_t featureFlags) {
+void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties,
+                              const VkPhysicalDeviceFeatures& features) {
     GrShaderCaps* shaderCaps = fShaderCaps.get();
     shaderCaps->fVersionDeclString = "#version 330\n";
 
@@ -385,10 +384,10 @@
 
     shaderCaps->fShaderDerivativeSupport = true;
 
-    shaderCaps->fGeometryShaderSupport = SkToBool(featureFlags & kGeometryShader_GrVkFeatureFlag);
+    shaderCaps->fGeometryShaderSupport = features.geometryShader;
     shaderCaps->fGSInvocationsSupport = shaderCaps->fGeometryShaderSupport;
 
-    shaderCaps->fDualSourceBlendingSupport = SkToBool(featureFlags & kDualSrcBlend_GrVkFeatureFlag);
+    shaderCaps->fDualSourceBlendingSupport = features.dualSrcBlend;
 
     shaderCaps->fIntegerSupport = true;
     shaderCaps->fVertexIDSupport = true;
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 7d9dbff..3eb5b48 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -27,7 +27,7 @@
      * be called to fill out the caps.
      */
     GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
-             VkPhysicalDevice device, uint32_t featureFlags);
+             VkPhysicalDevice device, const VkPhysicalDeviceFeatures& features);
 
     bool isConfigTexturable(GrPixelConfig config) const override {
         return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
@@ -146,11 +146,11 @@
     };
 
     void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
-              VkPhysicalDevice device, uint32_t featureFlags);
+              VkPhysicalDevice device, const VkPhysicalDeviceFeatures&);
     void initGrCaps(const VkPhysicalDeviceProperties&,
                     const VkPhysicalDeviceMemoryProperties&,
-                    uint32_t featureFlags);
-    void initShaderCaps(const VkPhysicalDeviceProperties&, uint32_t featureFlags);
+                    const VkPhysicalDeviceFeatures&);
+    void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures&);
 
 #ifdef GR_TEST_UTILS
     GrBackendFormat onCreateFormatFromBackendTexture(const GrBackendTexture&) const override;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 6a37c27..edb4b77 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -114,8 +114,23 @@
 
     fCompiler = new SkSL::Compiler();
 
-    fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
-                               backendContext.fFeatures));
+    if (backendContext.fFeatures & kIgnoreAllFlags_GrVkFeatureFlag) {
+        fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
+                                   backendContext.fDeviceFeatures));
+    } else {
+        VkPhysicalDeviceFeatures features;
+        if (backendContext.fFeatures & kGeometryShader_GrVkFeatureFlag) {
+            features.geometryShader = true;
+        }
+        if (backendContext.fFeatures & kDualSrcBlend_GrVkFeatureFlag) {
+            features.dualSrcBlend = true;
+        }
+        if (backendContext.fFeatures & kSampleRateShading_GrVkFeatureFlag) {
+            features.sampleRateShading = true;
+        }
+        fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
+                                   features));
+    }
     fCaps.reset(SkRef(fVkCaps.get()));
 
     VK_CALL(GetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &fPhysDevProps));
diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp
index faf7e90..3b81953 100644
--- a/tools/gpu/vk/VkTestUtils.cpp
+++ b/tools/gpu/vk/VkTestUtils.cpp
@@ -514,17 +514,6 @@
     // and we can't depend on it on all platforms
     deviceFeatures.robustBufferAccess = VK_FALSE;
 
-    uint32_t featureFlags = 0;
-    if (deviceFeatures.geometryShader) {
-        featureFlags |= kGeometryShader_GrVkFeatureFlag;
-    }
-    if (deviceFeatures.dualSrcBlend) {
-        featureFlags |= kDualSrcBlend_GrVkFeatureFlag;
-    }
-    if (deviceFeatures.sampleRateShading) {
-        featureFlags |= kSampleRateShading_GrVkFeatureFlag;
-    }
-
     float queuePriorities[1] = { 0.0 };
     // Here we assume no need for swapchain queue
     // If one is needed, the client will need its own setup code
@@ -584,7 +573,7 @@
     ctx->fGraphicsQueueIndex = graphicsQueueIndex;
     ctx->fMinAPIVersion = kGrVkMinimumVersion;
     ctx->fVkExtensions = extensions;
-    ctx->fFeatures = featureFlags;
+    ctx->fDeviceFeatures = deviceFeatures;
     ctx->fGetProc = getProc;
     ctx->fOwnsInstanceAndDevice = false;