=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d: Trace VK_EXT_vertex_attribute_divisor features.

Alexandre Julliard julliard at winehq.org
Thu Oct 25 15:23:43 CDT 2018


Module: vkd3d
Branch: master
Commit: db2788374089993f86036004ea7478376eb19a27
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=db2788374089993f86036004ea7478376eb19a27

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Thu Oct 25 13:41:10 2018 +0200

vkd3d: Trace VK_EXT_vertex_attribute_divisor features.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d/device.c        | 87 ++++++++++++++++++++++++++++++++++++++++------
 libs/vkd3d/vkd3d_private.h |  2 ++
 2 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index be8c15e..e9a3963 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -41,6 +41,26 @@ static const void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
     return NULL;
 }
 
+struct vk_struct
+{
+    VkStructureType sType;
+    struct vk_struct *pNext;
+};
+
+#define vk_find_struct(c, t) vk_find_struct_(c, VK_STRUCTURE_TYPE_##t)
+static const void *vk_find_struct_(struct vk_struct *chain, VkStructureType sType)
+{
+    while (chain)
+    {
+        if (chain->sType == sType)
+            return chain;
+
+        chain = chain->pNext;
+    }
+
+    return NULL;
+}
+
 struct vkd3d_optional_extension_info
 {
     const char *extension_name;
@@ -68,6 +88,19 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
             offsetof(struct vkd3d_vulkan_info, EXT_vertex_attribute_divisor)},
 };
 
+static unsigned int get_spec_version(const VkExtensionProperties *extensions,
+        unsigned int count, const char *extension_name)
+{
+    unsigned int i;
+
+    for (i = 0; i < count; ++i)
+    {
+        if (!strcmp(extensions[i].extensionName, extension_name))
+            return extensions[i].specVersion;
+    }
+    return 0;
+}
+
 static bool is_extension_disabled(const char *extension_name)
 {
     const char *disabled_extensions;
@@ -705,6 +738,7 @@ static void vkd3d_trace_physical_device(VkPhysicalDevice device,
 
 static void vkd3d_trace_physical_device_features(const VkPhysicalDeviceFeatures2KHR *features2)
 {
+    const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features;
     const VkPhysicalDeviceFeatures *features = &features2->features;
 
     TRACE("Device features:\n");
@@ -763,16 +797,26 @@ static void vkd3d_trace_physical_device_features(const VkPhysicalDeviceFeatures2
     TRACE("  sparseResidencyAliased: %#x.\n", features->sparseResidencyAliased);
     TRACE("  variableMultisampleRate: %#x.\n", features->variableMultisampleRate);
     TRACE("  inheritedQueries: %#x.\n", features->inheritedQueries);
+
+    divisor_features = vk_find_struct(features2->pNext, PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT);
+    if (divisor_features)
+    {
+        TRACE("  VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT:\n");
+        TRACE("    vertexAttributeInstanceRateDivisor: %#x.\n",
+                divisor_features->vertexAttributeInstanceRateDivisor);
+        TRACE("    vertexAttributeInstanceRateZeroDivisor: %#x.\n",
+                divisor_features->vertexAttributeInstanceRateZeroDivisor);
+    }
 }
 
-static void vkd3d_check_feature_level_11_requirements(const VkPhysicalDeviceLimits *limits,
+static void vkd3d_check_feature_level_11_requirements(const struct vkd3d_vulkan_info *vk_info,
         const VkPhysicalDeviceFeatures *features)
 {
 #define CHECK_MIN_REQUIREMENT(name, value) \
-    if (limits->name < value) \
+    if (vk_info->device_limits.name < value) \
         WARN(#name " does not meet feature level 11_0 requirements.\n");
 #define CHECK_MAX_REQUIREMENT(name, value) \
-    if (limits->name > value) \
+    if (vk_info->device_limits.name > value) \
         WARN(#name " does not meet feature level 11_0 requirements.\n");
 #define CHECK_FEATURE(name) \
     if (!features->name) \
@@ -807,6 +851,11 @@ static void vkd3d_check_feature_level_11_requirements(const VkPhysicalDeviceLimi
     CHECK_FEATURE(shaderClipDistance);
     CHECK_FEATURE(shaderCullDistance);
 
+    if (!vk_info->EXT_vertex_attribute_divisor)
+        WARN("Vertex attribute instance rate divisor is not supported.\n");
+    else if (!vk_info->vertex_attrib_zero_divisor)
+        WARN("Vertex attribute instance rate zero divisor is not supported.\n");
+
 #undef CHECK_MIN_REQUIREMENT
 #undef CHECK_MAX_REQUIREMENT
 #undef CHECK_FEATURE
@@ -814,10 +863,12 @@ static void vkd3d_check_feature_level_11_requirements(const VkPhysicalDeviceLimi
 
 static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
         const struct vkd3d_device_create_info *create_info,
-        const VkPhysicalDeviceFeatures *features, uint32_t *device_extension_count)
+        VkPhysicalDeviceFeatures2KHR *features2, uint32_t *device_extension_count)
 {
     const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
+    const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features;
     VkPhysicalDevice physical_device = device->vk_physical_device;
+    VkPhysicalDeviceFeatures *features = &features2->features;
     struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
     VkPhysicalDeviceProperties device_properties;
     VkExtensionProperties *vk_extensions;
@@ -826,12 +877,12 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
 
     *device_extension_count = 0;
 
+    vkd3d_trace_physical_device_features(features2);
+
     VK_CALL(vkGetPhysicalDeviceProperties(physical_device, &device_properties));
     vulkan_info->device_limits = device_properties.limits;
     vulkan_info->sparse_properties = device_properties.sparseProperties;
 
-    vkd3d_check_feature_level_11_requirements(&device_properties.limits, features);
-
     device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64;
     device->feature_options.OutputMergerLogicOp = features->logicOp;
     /* SPV_KHR_16bit_storage */
@@ -894,7 +945,25 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
             create_info->device_extensions, create_info->device_extension_count,
             NULL, 0, NULL, vulkan_info, "device");
 
+    divisor_features = vk_find_struct(features2->pNext, PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT);
+    if (get_spec_version(vk_extensions, count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3
+            && divisor_features)
+    {
+        if (!divisor_features->vertexAttributeInstanceRateDivisor)
+            vulkan_info->EXT_vertex_attribute_divisor = false;
+        vulkan_info->vertex_attrib_zero_divisor = divisor_features->vertexAttributeInstanceRateZeroDivisor;
+    }
+    else
+    {
+        vulkan_info->vertex_attrib_zero_divisor = false;
+    }
+
+    vkd3d_check_feature_level_11_requirements(vulkan_info, features);
+
+    features->shaderTessellationAndGeometryPointSize = VK_FALSE;
+
     vkd3d_free(vk_extensions);
+
     return S_OK;
 }
 
@@ -1098,13 +1167,9 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
     else
         VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2.features));
 
-    vkd3d_trace_physical_device_features(&features2);
-
-    if (FAILED(hr = vkd3d_init_device_caps(device, create_info, &features2.features, &extension_count)))
+    if (FAILED(hr = vkd3d_init_device_caps(device, create_info, &features2, &extension_count)))
         goto done;
 
-    features2.features.shaderTessellationAndGeometryPointSize = VK_FALSE;
-
     if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions))))
     {
         hr = E_OUTOFMEMORY;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index e4e1e11..3f53980 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -85,6 +85,8 @@ struct vkd3d_vulkan_info
     bool KHR_push_descriptor;
     bool EXT_vertex_attribute_divisor;
 
+    bool vertex_attrib_zero_divisor;
+
     VkPhysicalDeviceLimits device_limits;
     VkPhysicalDeviceSparseProperties sparse_properties;
 };




More information about the wine-cvs mailing list