1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 03:45:57 +00:00

wined3d: Allow creating a feature level 9.3 device even if custom vertex attribute divisors are not supported.

This commit is contained in:
Zebediah Figura 2022-07-06 20:17:29 -05:00 committed by Alexandre Julliard
parent 15460d237b
commit b875d395d1

View File

@ -376,19 +376,43 @@ static const struct wined3d_allocator_ops wined3d_allocator_vk_ops =
.allocator_destroy_chunk = wined3d_allocator_vk_destroy_chunk,
};
static void get_physical_device_info(const struct wined3d_adapter_vk *adapter_vk, struct wined3d_physical_device_info *info)
{
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features = &info->vertex_divisor_features;
VkPhysicalDeviceHostQueryResetFeatures *host_query_reset_features = &info->host_query_reset_features;
VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features = &info->xfb_features;
VkPhysicalDevice physical_device = adapter_vk->physical_device;
const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
VkPhysicalDeviceFeatures2 *features2 = &info->features2;
memset(info, 0, sizeof(*info));
xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
vertex_divisor_features->pNext = xfb_features;
host_query_reset_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
host_query_reset_features->pNext = vertex_divisor_features;
features2->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
features2->pNext = host_query_reset_features;
if (vk_info->vk_ops.vkGetPhysicalDeviceFeatures2)
VK_CALL(vkGetPhysicalDeviceFeatures2(physical_device, features2));
else
VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2->features));
}
static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
const enum wined3d_feature_level *levels, unsigned int level_count,
struct wined3d_device_parent *device_parent, struct wined3d_device **device)
{
const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter);
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features;
VkPhysicalDeviceHostQueryResetFeatures *host_query_reset_features;
const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features;
struct wined3d_physical_device_info physical_device_info;
static const float priorities[] = {1.0f};
VkPhysicalDeviceFeatures2 *features2;
struct wined3d_device_vk *device_vk;
VkDevice vk_device = VK_NULL_HANDLE;
VkDeviceQueueCreateInfo queue_info;
@ -407,36 +431,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
physical_device = adapter_vk->physical_device;
memset(&physical_device_info, 0, sizeof(physical_device_info));
xfb_features = &physical_device_info.xfb_features;
xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
vertex_divisor_features = &physical_device_info.vertex_divisor_features;
vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
vertex_divisor_features->pNext = xfb_features;
host_query_reset_features = &physical_device_info.host_query_reset_features;
host_query_reset_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
host_query_reset_features->pNext = vertex_divisor_features;
features2 = &physical_device_info.features2;
features2->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
features2->pNext = host_query_reset_features;
if (vk_info->vk_ops.vkGetPhysicalDeviceFeatures2)
VK_CALL(vkGetPhysicalDeviceFeatures2(physical_device, features2));
else
VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2->features));
if (!vertex_divisor_features->vertexAttributeInstanceRateDivisor
|| !vertex_divisor_features->vertexAttributeInstanceRateZeroDivisor)
{
WARN("Vertex attribute divisors not supported.\n");
hr = E_FAIL;
goto fail;
}
get_physical_device_info(adapter_vk, &physical_device_info);
wined3d_disable_vulkan_features(&physical_device_info);
queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@ -447,7 +442,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
queue_info.pQueuePriorities = priorities;
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_info.pNext = features2->pNext;
device_info.pNext = physical_device_info.features2.pNext;
device_info.flags = 0;
device_info.queueCreateInfoCount = 1;
device_info.pQueueCreateInfos = &queue_info;
@ -455,7 +450,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
device_info.ppEnabledLayerNames = NULL;
device_info.enabledExtensionCount = adapter_vk->device_extension_count;
device_info.ppEnabledExtensionNames = adapter_vk->device_extensions;
device_info.pEnabledFeatures = &features2->features;
device_info.pEnabledFeatures = &physical_device_info.features2.features;
if ((vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device))) < 0)
{
@ -2251,7 +2246,15 @@ static bool adapter_vk_init_driver_info(struct wined3d_adapter_vk *adapter_vk,
adapter_vk->a.d3d_info.feature_level, vram_bytes, sysmem_bytes);
}
static enum wined3d_feature_level feature_level_from_caps(const struct shader_caps *shader_caps)
static bool feature_level_10_supported(const struct wined3d_physical_device_info *info, unsigned int shader_model)
{
return shader_model >= 4
&& info->vertex_divisor_features.vertexAttributeInstanceRateDivisor
&& info->vertex_divisor_features.vertexAttributeInstanceRateZeroDivisor;
}
static enum wined3d_feature_level feature_level_from_caps(const struct wined3d_physical_device_info *info,
const struct shader_caps *shader_caps)
{
unsigned int shader_model;
@ -2269,7 +2272,7 @@ static enum wined3d_feature_level feature_level_from_caps(const struct shader_ca
if (shader_model <= 2)
return WINED3D_FEATURE_LEVEL_9_2;
if (shader_model <= 3)
if (!feature_level_10_supported(info, shader_model))
return WINED3D_FEATURE_LEVEL_9_3;
if (shader_model <= 4)
@ -2281,10 +2284,13 @@ static enum wined3d_feature_level feature_level_from_caps(const struct shader_ca
static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_vk, uint32_t wined3d_creation_flags)
{
struct wined3d_d3d_info *d3d_info = &adapter_vk->a.d3d_info;
struct wined3d_physical_device_info device_info;
struct wined3d_vertex_caps vertex_caps;
struct fragment_caps fragment_caps;
struct shader_caps shader_caps;
get_physical_device_info(adapter_vk, &device_info);
adapter_vk->a.shader_backend->shader_get_caps(&adapter_vk->a, &shader_caps);
adapter_vk->a.vertex_pipe->vp_get_caps(&adapter_vk->a, &vertex_caps);
adapter_vk->a.fragment_pipe->get_caps(&adapter_vk->a, &fragment_caps);
@ -2330,7 +2336,7 @@ static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_
d3d_info->full_ffp_varyings = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_FULL_FFP_VARYINGS);
d3d_info->scaled_resolve = false;
d3d_info->pbo = true;
d3d_info->feature_level = feature_level_from_caps(&shader_caps);
d3d_info->feature_level = feature_level_from_caps(&device_info, &shader_caps);
d3d_info->subpixel_viewport = true;
d3d_info->fences = true;
d3d_info->persistent_map = true;