wined3d: Use Vulkan physical device properties to fill GPU description.
[wine.git] / dlls / wined3d / adapter_vk.c
blob5c4bdd0d300969b6868ef71a0cc2802012a97322
1 /*
2 * Copyright 2018 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wined3d_private.h"
23 #include "wine/vulkan_driver.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
27 #ifdef USE_WIN32_VULKAN
28 static BOOL wined3d_load_vulkan(struct wined3d_vk_info *vk_info)
30 struct vulkan_ops *vk_ops = &vk_info->vk_ops;
32 if (!(vk_info->vulkan_lib = LoadLibraryA("vulkan-1.dll")))
34 WARN("Failed to load vulkan-1.dll.\n");
35 return FALSE;
38 vk_ops->vkGetInstanceProcAddr = (void *)GetProcAddress(vk_info->vulkan_lib, "vkGetInstanceProcAddr");
39 if (!vk_ops->vkGetInstanceProcAddr)
41 FreeLibrary(vk_info->vulkan_lib);
42 return FALSE;
45 return TRUE;
48 static void wined3d_unload_vulkan(struct wined3d_vk_info *vk_info)
50 if (vk_info->vulkan_lib)
52 FreeLibrary(vk_info->vulkan_lib);
53 vk_info->vulkan_lib = NULL;
56 #else
57 static BOOL wined3d_load_vulkan(struct wined3d_vk_info *vk_info)
59 struct vulkan_ops *vk_ops = &vk_info->vk_ops;
60 const struct vulkan_funcs *vk_funcs;
61 HDC dc;
63 dc = GetDC(0);
64 vk_funcs = __wine_get_vulkan_driver(dc, WINE_VULKAN_DRIVER_VERSION);
65 ReleaseDC(0, dc);
67 if (!vk_funcs)
68 return FALSE;
70 vk_ops->vkGetInstanceProcAddr = (void *)vk_funcs->p_vkGetInstanceProcAddr;
71 return TRUE;
74 static void wined3d_unload_vulkan(struct wined3d_vk_info *vk_info) {}
75 #endif
77 static void adapter_vk_destroy(struct wined3d_adapter *adapter)
79 struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(adapter);
80 struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
82 VK_CALL(vkDestroyInstance(vk_info->instance, NULL));
83 wined3d_unload_vulkan(vk_info);
84 wined3d_adapter_cleanup(&adapter_vk->a);
85 heap_free(adapter_vk);
88 static BOOL adapter_vk_create_context(struct wined3d_context *context,
89 struct wined3d_texture *target, const struct wined3d_format *ds_format)
91 return TRUE;
94 static void adapter_vk_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
98 static BOOL adapter_vk_check_format(const struct wined3d_adapter *adapter,
99 const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format,
100 const struct wined3d_format *ds_format)
102 return TRUE;
105 static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
107 adapter_vk_destroy,
108 adapter_vk_create_context,
109 adapter_vk_get_wined3d_caps,
110 adapter_vk_check_format,
113 static unsigned int wined3d_get_wine_vk_version(void)
115 const char *ptr = PACKAGE_VERSION;
116 int major, minor;
118 major = atoi(ptr);
120 while (isdigit(*ptr) || *ptr == '.')
121 ++ptr;
123 minor = atoi(ptr);
125 return VK_MAKE_VERSION(major, minor, 0);
128 static BOOL wined3d_init_vulkan(struct wined3d_vk_info *vk_info)
130 struct vulkan_ops *vk_ops = &vk_info->vk_ops;
131 VkInstance instance = VK_NULL_HANDLE;
132 VkInstanceCreateInfo instance_info;
133 VkApplicationInfo app_info;
134 char app_name[MAX_PATH];
135 VkResult vr;
137 if (!wined3d_load_vulkan(vk_info))
138 return FALSE;
140 if (!(vk_ops->vkCreateInstance = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkCreateInstance"))))
142 ERR("Could not get 'vkCreateInstance'.\n");
143 goto fail;
146 memset(&app_info, 0, sizeof(app_info));
147 app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
148 if (wined3d_get_app_name(app_name, ARRAY_SIZE(app_name)))
149 app_info.pApplicationName = app_name;
150 app_info.pEngineName = "Damavand";
151 app_info.engineVersion = wined3d_get_wine_vk_version();
152 app_info.apiVersion = VK_API_VERSION_1_0;
154 memset(&instance_info, 0, sizeof(instance_info));
155 instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
156 instance_info.pApplicationInfo = &app_info;
157 if ((vr = VK_CALL(vkCreateInstance(&instance_info, NULL, &instance))) < 0)
159 WARN("Failed to create Vulkan instance, vr %d.\n", vr);
160 goto fail;
163 TRACE("Created Vulkan instance %p.\n", instance);
165 #define LOAD_INSTANCE_PFN(name) \
166 if (!(vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name)))) \
168 WARN("Could not get instance proc addr for '" #name "'.\n"); \
169 goto fail; \
171 #define VK_INSTANCE_PFN LOAD_INSTANCE_PFN
172 #define VK_DEVICE_PFN LOAD_INSTANCE_PFN
173 VK_INSTANCE_FUNCS()
174 VK_DEVICE_FUNCS()
175 #undef VK_INSTANCE_PFN
176 #undef VK_DEVICE_PFN
178 vk_info->instance = instance;
180 return TRUE;
182 fail:
183 if (vk_ops->vkDestroyInstance)
184 VK_CALL(vkDestroyInstance(instance, NULL));
185 wined3d_unload_vulkan(vk_info);
186 return FALSE;
189 static VkPhysicalDevice get_vulkan_physical_device(struct wined3d_vk_info *vk_info)
191 VkPhysicalDevice physical_devices[1];
192 uint32_t count;
193 VkResult vr;
195 if ((vr = VK_CALL(vkEnumeratePhysicalDevices(vk_info->instance, &count, NULL))) < 0)
197 WARN("Failed to enumerate physical devices, vr %d.\n", vr);
198 return VK_NULL_HANDLE;
200 if (!count)
202 WARN("No physical device.\n");
203 return VK_NULL_HANDLE;
205 if (count > 1)
207 /* TODO: Create wined3d_adapter for each device. */
208 FIXME("Multiple physical devices available.\n");
209 count = 1;
212 if ((vr = VK_CALL(vkEnumeratePhysicalDevices(vk_info->instance, &count, physical_devices))) < 0)
214 WARN("Failed to get physical devices, vr %d.\n", vr);
215 return VK_NULL_HANDLE;
218 return physical_devices[0];
221 const struct wined3d_gpu_description *get_vulkan_gpu_description(const struct wined3d_vk_info *vk_info,
222 VkPhysicalDevice physical_device)
224 const struct wined3d_gpu_description *description;
225 VkPhysicalDeviceProperties properties;
227 VK_CALL(vkGetPhysicalDeviceProperties(physical_device, &properties));
229 TRACE("Device name: %s.\n", debugstr_a(properties.deviceName));
230 TRACE("Vendor ID: 0x%04x, Device ID: 0x%04x.\n", properties.vendorID, properties.deviceID);
231 TRACE("Driver version: %#x.\n", properties.driverVersion);
232 TRACE("API version: %u.%u.%u.\n", VK_VERSION_MAJOR(properties.apiVersion),
233 VK_VERSION_MINOR(properties.apiVersion), VK_VERSION_PATCH(properties.apiVersion));
235 if ((description = wined3d_get_gpu_description(properties.vendorID, properties.deviceID)))
236 return description;
238 FIXME("Failed to retrieve GPU description for device %s %04x:%04x.\n",
239 debugstr_a(properties.deviceName), properties.vendorID, properties.deviceID);
241 return wined3d_get_gpu_description(HW_VENDOR_AMD, CARD_AMD_RADEON_RX_VEGA);
244 static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk,
245 unsigned int ordinal, unsigned int wined3d_creation_flags)
247 struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
248 const struct wined3d_gpu_description *gpu_description;
249 struct wined3d_adapter *adapter = &adapter_vk->a;
251 TRACE("adapter_vk %p, ordinal %u, wined3d_creation_flags %#x.\n",
252 adapter_vk, ordinal, wined3d_creation_flags);
254 if (!wined3d_adapter_init(adapter, ordinal))
255 return FALSE;
257 if (!wined3d_init_vulkan(vk_info))
259 WARN("Failed to initialize Vulkan.\n");
260 goto fail;
263 if (!(adapter_vk->physical_device = get_vulkan_physical_device(vk_info)))
264 goto fail_vulkan;
266 if (!(gpu_description = get_vulkan_gpu_description(vk_info, adapter_vk->physical_device)))
268 ERR("Failed to get GPU description.\n");
269 goto fail_vulkan;
271 wined3d_driver_info_init(&adapter->driver_info, gpu_description, wined3d_settings.emulated_textureram);
273 if (!wined3d_adapter_vk_init_format_info(adapter))
274 goto fail_vulkan;
276 adapter->vertex_pipe = &none_vertex_pipe;
277 adapter->fragment_pipe = &none_fragment_pipe;
278 adapter->shader_backend = &none_shader_backend;
279 adapter->adapter_ops = &wined3d_adapter_vk_ops;
281 adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags;
283 return TRUE;
285 fail_vulkan:
286 VK_CALL(vkDestroyInstance(vk_info->instance, NULL));
287 wined3d_unload_vulkan(vk_info);
288 fail:
289 wined3d_adapter_cleanup(adapter);
290 return FALSE;
293 struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal,
294 unsigned int wined3d_creation_flags)
296 struct wined3d_adapter_vk *adapter_vk;
298 if (!(adapter_vk = heap_alloc_zero(sizeof(*adapter_vk))))
299 return NULL;
301 if (!wined3d_adapter_vk_init(adapter_vk, ordinal, wined3d_creation_flags))
303 heap_free(adapter_vk);
304 return NULL;
307 TRACE("Created adapter %p.\n", adapter_vk);
309 return &adapter_vk->a;