Add support for Advanced blend extension to vulkan.
Currently we only support coherent advanced blends
Bug: skia:
Change-Id: I3d0d7d19313dc55aed57c79585c0ee870f6981a7
Reviewed-on: https://skia-review.googlesource.com/145888
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 7f67f7c..28440b1 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -239,7 +239,7 @@
fSupportsMaintenance3 = true;
}
- this->initGrCaps(properties, memoryProperties, features);
+ this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions);
this->initShaderCaps(properties, features);
if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
@@ -344,9 +344,33 @@
return 64;
}
-void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
+template<typename T> T* get_extension_feature_struct(const VkPhysicalDeviceFeatures2& features,
+ VkStructureType type) {
+ // All Vulkan structs that could be part of the features chain will start with the
+ // structure type followed by the pNext pointer. We cast to the CommonVulkanHeader
+ // so we can get access to the pNext for the next struct.
+ struct CommonVulkanHeader {
+ VkStructureType sType;
+ void* pNext;
+ };
+
+ void* pNext = features.pNext;
+ while (pNext) {
+ CommonVulkanHeader* header = static_cast<CommonVulkanHeader*>(pNext);
+ if (header->sType == type) {
+ return static_cast<T*>(pNext);
+ }
+ pNext = header->pNext;
+ }
+ return nullptr;
+}
+
+void GrVkCaps::initGrCaps(const GrVkInterface* vkInterface,
+ VkPhysicalDevice physDev,
+ const VkPhysicalDeviceProperties& properties,
const VkPhysicalDeviceMemoryProperties& memoryProperties,
- const VkPhysicalDeviceFeatures2& features) {
+ const VkPhysicalDeviceFeatures2& features,
+ const GrVkExtensions& extensions) {
// 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
@@ -376,6 +400,37 @@
fOversizedStencilSupport = true;
fSampleShadingSupport = features.features.sampleRateShading;
+
+ if (extensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2) &&
+ this->supportsPhysicalDeviceProperties2()) {
+
+ VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT blendProps;
+ blendProps.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT;
+ blendProps.pNext = nullptr;
+
+ VkPhysicalDeviceProperties2 props;
+ props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ props.pNext = &blendProps;
+
+ GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties2(physDev, &props));
+
+ if (blendProps.advancedBlendAllOperations == VK_TRUE) {
+ fShaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
+
+ auto blendFeatures =
+ get_extension_feature_struct<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>(
+ features,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT);
+ if (blendFeatures && blendFeatures->advancedBlendCoherentOperations == VK_TRUE) {
+ fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
+ } else {
+ // TODO: Currently non coherent blends are not supported in our vulkan backend. They
+ // require us to support self dependencies in our render passes.
+ // fBlendEquationSupport = kAdvanced_BlendEquationSupport;
+ }
+ }
+ }
}
void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties,