=?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