Mesa (main): zink/codegen: do not include compilation structs with extension structs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 3 13:27:50 UTC 2022


Module: Mesa
Branch: main
Commit: 07565e8852970777ffe552f20444de4cd8e2f4c8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=07565e8852970777ffe552f20444de4cd8e2f4c8

Author: Hoe Hao Cheng <haochengho12907 at gmail.com>
Date:   Sun May  1 17:29:08 2022 +0800

zink/codegen: do not include compilation structs with extension structs

(compilation structs refer to VkPhysicalDeviceVulkanXYFeatures/Properties, as
they consist of all features added by extensions promoted in VK X.Y)

The spec prohibits this, so instead we map the fields in the compilation
structs onto the fields in extension structs.

Some extensions' feature/properties structs are not promoted, and the spec
allows including both compilation structs and extension structs in such cases.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16265>

---

 src/gallium/drivers/zink/zink_device_info.py | 46 ++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py
index dc92f35795b..313275f5ad3 100644
--- a/src/gallium/drivers/zink/zink_device_info.py
+++ b/src/gallium/drivers/zink/zink_device_info.py
@@ -422,7 +422,11 @@ zink_get_physical_device_info(struct zink_screen *screen)
 %for ext in extensions:
 %if ext.has_features:
 <%helpers:guard ext="${ext}">
+%if ext.features_promoted:
+      if (support_${ext.name_with_vendor()} && !info->have_vulkan${ext.core_since.struct()}) {
+%else:
       if (support_${ext.name_with_vendor()}) {
+%endif
          info->${ext.field("feats")}.sType = ${ext.stype("FEATURES")};
          info->${ext.field("feats")}.pNext = info->feats.pNext;
          info->feats.pNext = &info->${ext.field("feats")};
@@ -457,7 +461,11 @@ zink_get_physical_device_info(struct zink_screen *screen)
 %for ext in extensions:
 %if ext.has_properties:
 <%helpers:guard ext="${ext}">
+%if ext.properties_promoted:
+      if (support_${ext.name_with_vendor()} && !info->have_vulkan${ext.core_since.struct()}) {
+%else:
       if (support_${ext.name_with_vendor()}) {
+%endif
          info->${ext.field("props")}.sType = ${ext.stype("PROPERTIES")};
          info->${ext.field("props")}.pNext = props.pNext;
          props.pNext = &info->${ext.field("props")};
@@ -482,6 +490,42 @@ zink_get_physical_device_info(struct zink_screen *screen)
       screen->vk.GetPhysicalDeviceProperties2(screen->pdev, &props);
    }
 
+   /* We re-apply the fields from VkPhysicalDeviceVulkanXYFeatures struct
+    * onto their respective fields in the VkPhysicalDeviceExtensionNameFeatures
+    * struct if the former is provided by the VK implementation.
+    *
+    * As for why this is done: the spec mentions that once an extension is
+    * promoted to core and its feature fields are added in VulkanXYFeatures,
+    * including both ExtensionNameFeatures and VulkanXYFeatures at the same
+    * time is prohibited when using vkGetPhysicalDeviceFeatures2.
+    */
+%for ext in extensions:
+%if ext.features_promoted:
+   if (info->have_vulkan${ext.core_since.struct()}) {
+    %for field in registry.get_registry_entry(ext.name).features_fields:
+      info->${ext.field("feats")}.${field} = info->feats${ext.core_since.struct()}.${field};
+    %endfor
+   }
+%endif
+%endfor
+
+   /* See above, but for VulkanXYProperties.
+    * Unlike VulkanXYFeatures with all the booleans, VulkanXYProperties can
+    * contain different types of data, including arrays. The C language hates us
+    * when we assign an array to another array, therefore we use an memcpy here.
+    */
+%for ext in extensions:
+%if ext.properties_promoted:
+   if (info->have_vulkan${ext.core_since.struct()}) {
+    %for field in registry.get_registry_entry(ext.name).properties_fields:
+      memcpy(&info->${ext.field("props")}.${field},
+             &info->props${ext.core_since.struct()}.${field},
+             sizeof(info->${ext.field("props")}.${field}));
+    %endfor
+   }
+%endif
+%endfor
+
    // enable the extensions if they match the conditions given by ext.enable_conds 
    if (screen->vk.GetPhysicalDeviceProperties2) {
         %for ext in extensions:
@@ -630,11 +674,13 @@ if __name__ == "__main__":
             if not (entry.features_struct and ext.physical_device_struct("Features") == entry.features_struct):
                 error_count += 1
                 print("The extension {} does not provide a features struct.".format(ext.name))
+            ext.features_promoted = entry.features_promoted
 
         if ext.has_properties:
             if not (entry.properties_struct and ext.physical_device_struct("Properties") == entry.properties_struct):
                 error_count += 1
                 print("The extension {} does not provide a properties struct.".format(ext.name))
+            ext.properties_promoted = entry.properties_promoted
 
         if entry.promoted_in:
             ext.core_since = Version((*entry.promoted_in, 0))



More information about the mesa-commit mailing list