Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Version 2: Do not call wined3d_adapter_cleanup() when wined3d_adapter_init() failed.
--- dlls/wined3d/adapter_vk.c | 80 +++++++++++++- dlls/wined3d/wined3d_private.h | 3 + dlls/wined3d/wined3d_vk.h | 186 +++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 dlls/wined3d/wined3d_vk.h
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index e2c940dae9d9..337c6f71946c 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -20,12 +20,18 @@ #include "wine/port.h" #include "wined3d_private.h"
+#include "wine/vulkan_driver.h" + WINE_DEFAULT_DEBUG_CHANNEL(d3d);
static void adapter_vk_destroy(struct wined3d_adapter *adapter) { - wined3d_adapter_cleanup(adapter); - heap_free(adapter); + struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(adapter); + const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; + + VK_CALL(vkDestroyInstance(vk_info->instance, NULL)); + wined3d_adapter_cleanup(&adapter_vk->a); + heap_free(adapter_vk); }
static BOOL adapter_vk_create_context(struct wined3d_context *context, @@ -53,9 +59,63 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops = adapter_vk_check_format, };
+static BOOL wined3d_init_vulkan(struct wined3d_vk_info *vk_info) +{ + struct vulkan_ops *vk_ops = &vk_info->vk_ops; + const struct vulkan_funcs *vk_funcs; + VkInstanceCreateInfo instance_info; + VkInstance instance; + VkResult vr; + HDC dc; + + dc = GetDC(0); + vk_funcs = __wine_get_vulkan_driver(dc, WINE_VULKAN_DRIVER_VERSION); + ReleaseDC(0, dc); + + if (!vk_funcs) + return FALSE; + + vk_ops->vkGetInstanceProcAddr = (void *)vk_funcs->p_vkGetInstanceProcAddr; + + if (!(vk_ops->vkCreateInstance = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkCreateInstance")))) + { + ERR("Could not get 'vkCreateInstance'.\n"); + return FALSE; + } + + memset(&instance_info, 0, sizeof(instance_info)); + instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + if ((vr = VK_CALL(vkCreateInstance(&instance_info, NULL, &instance))) < 0) + { + WARN("Failed to create Vulkan instance, vr %d.\n", vr); + return FALSE; + } + + TRACE("Created Vulkan instance %p.\n", instance); + +#define LOAD_INSTANCE_PFN(name) \ + if (!(vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name)))) \ + { \ + WARN("Could not get instance proc addr for '" #name "'.\n"); \ + vk_funcs->p_vkDestroyInstance(instance, NULL); \ + return FALSE; \ + } +#define VK_INSTANCE_PFN LOAD_INSTANCE_PFN +#define VK_DEVICE_PFN LOAD_INSTANCE_PFN + VK_INSTANCE_FUNCS() + VK_DEVICE_FUNCS() +#undef VK_INSTANCE_PFN +#undef VK_DEVICE_PFN + + vk_info->instance = instance; + + return TRUE; +} + static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk, unsigned int ordinal, unsigned int wined3d_creation_flags) { + struct wined3d_vk_info *vk_info = &adapter_vk->vk_info; const struct wined3d_gpu_description *gpu_description; struct wined3d_adapter *adapter = &adapter_vk->a;
@@ -65,15 +125,21 @@ static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk, if (!wined3d_adapter_init(adapter, ordinal)) return FALSE;
+ if (!wined3d_init_vulkan(vk_info)) + { + WARN("Failed to initialize Vulkan.\n"); + goto fail; + } + if (!(gpu_description = wined3d_get_gpu_description(HW_VENDOR_AMD, CARD_AMD_RADEON_RX_VEGA))) { ERR("Failed to get GPU description.\n"); - return FALSE; + goto fail; } wined3d_driver_info_init(&adapter->driver_info, gpu_description, wined3d_settings.emulated_textureram);
if (!wined3d_adapter_vk_init_format_info(adapter)) - return FALSE; + goto fail;
adapter->vertex_pipe = &none_vertex_pipe; adapter->fragment_pipe = &none_fragment_pipe; @@ -83,6 +149,12 @@ static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk, adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags;
return TRUE; + +fail: + if (vk_info->vk_ops.vkDestroyInstance) + VK_CALL(vkDestroyInstance(vk_info->instance, NULL)); + wined3d_adapter_cleanup(adapter); + return FALSE; }
struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5a455edb0c2f..012c90f5d345 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -54,6 +54,7 @@ #include "objbase.h" #include "wine/wined3d.h" #include "wined3d_gl.h" +#include "wined3d_vk.h" #include "wine/list.h" #include "wine/rbtree.h" #include "wine/wgl_driver.h" @@ -2752,6 +2753,8 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context, struct wined3d_adapter_vk { struct wined3d_adapter a; + + struct wined3d_vk_info vk_info; };
static inline struct wined3d_adapter_vk *wined3d_adapter_vk(struct wined3d_adapter *adapter) diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h new file mode 100644 index 000000000000..ac59a2dcd1ab --- /dev/null +++ b/dlls/wined3d/wined3d_vk.h @@ -0,0 +1,186 @@ +/* + * Copyright 2018 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINED3D_VK_H +#define __WINE_WINED3D_VK_H + +#define VK_NO_PROTOTYPES +#define WINE_VK_HOST +#include "wine/vulkan.h" + +#define VK_INSTANCE_FUNCS() \ + VK_INSTANCE_PFN(vkCreateDevice) \ + VK_INSTANCE_PFN(vkDestroyInstance) \ + VK_INSTANCE_PFN(vkEnumerateDeviceExtensionProperties) \ + VK_INSTANCE_PFN(vkEnumerateDeviceLayerProperties) \ + VK_INSTANCE_PFN(vkEnumeratePhysicalDevices) \ + VK_INSTANCE_PFN(vkGetDeviceProcAddr) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceFormatProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceImageFormatProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceMemoryProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceQueueFamilyProperties) \ + VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties) + +#define VK_DEVICE_FUNCS() \ + VK_DEVICE_PFN(vkAllocateCommandBuffers) \ + VK_DEVICE_PFN(vkAllocateDescriptorSets) \ + VK_DEVICE_PFN(vkAllocateMemory) \ + VK_DEVICE_PFN(vkBeginCommandBuffer) \ + VK_DEVICE_PFN(vkBindBufferMemory) \ + VK_DEVICE_PFN(vkBindImageMemory) \ + VK_DEVICE_PFN(vkCmdBeginQuery) \ + VK_DEVICE_PFN(vkCmdBeginRenderPass) \ + VK_DEVICE_PFN(vkCmdBindDescriptorSets) \ + VK_DEVICE_PFN(vkCmdBindIndexBuffer) \ + VK_DEVICE_PFN(vkCmdBindPipeline) \ + VK_DEVICE_PFN(vkCmdBindVertexBuffers) \ + VK_DEVICE_PFN(vkCmdBlitImage) \ + VK_DEVICE_PFN(vkCmdClearAttachments) \ + VK_DEVICE_PFN(vkCmdClearColorImage) \ + VK_DEVICE_PFN(vkCmdClearDepthStencilImage) \ + VK_DEVICE_PFN(vkCmdCopyBuffer) \ + VK_DEVICE_PFN(vkCmdCopyBufferToImage) \ + VK_DEVICE_PFN(vkCmdCopyImage) \ + VK_DEVICE_PFN(vkCmdCopyImageToBuffer) \ + VK_DEVICE_PFN(vkCmdCopyQueryPoolResults) \ + VK_DEVICE_PFN(vkCmdDispatch) \ + VK_DEVICE_PFN(vkCmdDispatchIndirect) \ + VK_DEVICE_PFN(vkCmdDraw) \ + VK_DEVICE_PFN(vkCmdDrawIndexed) \ + VK_DEVICE_PFN(vkCmdDrawIndexedIndirect) \ + VK_DEVICE_PFN(vkCmdDrawIndirect) \ + VK_DEVICE_PFN(vkCmdEndQuery) \ + VK_DEVICE_PFN(vkCmdEndRenderPass) \ + VK_DEVICE_PFN(vkCmdExecuteCommands) \ + VK_DEVICE_PFN(vkCmdFillBuffer) \ + VK_DEVICE_PFN(vkCmdNextSubpass) \ + VK_DEVICE_PFN(vkCmdPipelineBarrier) \ + VK_DEVICE_PFN(vkCmdPushConstants) \ + VK_DEVICE_PFN(vkCmdResetEvent) \ + VK_DEVICE_PFN(vkCmdResetQueryPool) \ + VK_DEVICE_PFN(vkCmdResolveImage) \ + VK_DEVICE_PFN(vkCmdSetBlendConstants) \ + VK_DEVICE_PFN(vkCmdSetDepthBias) \ + VK_DEVICE_PFN(vkCmdSetDepthBounds) \ + VK_DEVICE_PFN(vkCmdSetEvent) \ + VK_DEVICE_PFN(vkCmdSetLineWidth) \ + VK_DEVICE_PFN(vkCmdSetScissor) \ + VK_DEVICE_PFN(vkCmdSetStencilCompareMask) \ + VK_DEVICE_PFN(vkCmdSetStencilReference) \ + VK_DEVICE_PFN(vkCmdSetStencilWriteMask) \ + VK_DEVICE_PFN(vkCmdSetViewport) \ + VK_DEVICE_PFN(vkCmdUpdateBuffer) \ + VK_DEVICE_PFN(vkCmdWaitEvents) \ + VK_DEVICE_PFN(vkCmdWriteTimestamp) \ + VK_DEVICE_PFN(vkCreateBuffer) \ + VK_DEVICE_PFN(vkCreateBufferView) \ + VK_DEVICE_PFN(vkCreateCommandPool) \ + VK_DEVICE_PFN(vkCreateComputePipelines) \ + VK_DEVICE_PFN(vkCreateDescriptorPool) \ + VK_DEVICE_PFN(vkCreateDescriptorSetLayout) \ + VK_DEVICE_PFN(vkCreateEvent) \ + VK_DEVICE_PFN(vkCreateFence) \ + VK_DEVICE_PFN(vkCreateFramebuffer) \ + VK_DEVICE_PFN(vkCreateGraphicsPipelines) \ + VK_DEVICE_PFN(vkCreateImage) \ + VK_DEVICE_PFN(vkCreateImageView) \ + VK_DEVICE_PFN(vkCreatePipelineCache) \ + VK_DEVICE_PFN(vkCreatePipelineLayout) \ + VK_DEVICE_PFN(vkCreateQueryPool) \ + VK_DEVICE_PFN(vkCreateRenderPass) \ + VK_DEVICE_PFN(vkCreateSampler) \ + VK_DEVICE_PFN(vkCreateSemaphore) \ + VK_DEVICE_PFN(vkCreateShaderModule) \ + VK_DEVICE_PFN(vkDestroyBuffer) \ + VK_DEVICE_PFN(vkDestroyBufferView) \ + VK_DEVICE_PFN(vkDestroyCommandPool) \ + VK_DEVICE_PFN(vkDestroyDescriptorPool) \ + VK_DEVICE_PFN(vkDestroyDescriptorSetLayout) \ + VK_DEVICE_PFN(vkDestroyDevice) \ + VK_DEVICE_PFN(vkDestroyEvent) \ + VK_DEVICE_PFN(vkDestroyFence) \ + VK_DEVICE_PFN(vkDestroyFramebuffer) \ + VK_DEVICE_PFN(vkDestroyImage) \ + VK_DEVICE_PFN(vkDestroyImageView) \ + VK_DEVICE_PFN(vkDestroyPipeline) \ + VK_DEVICE_PFN(vkDestroyPipelineCache) \ + VK_DEVICE_PFN(vkDestroyPipelineLayout) \ + VK_DEVICE_PFN(vkDestroyQueryPool) \ + VK_DEVICE_PFN(vkDestroyRenderPass) \ + VK_DEVICE_PFN(vkDestroySampler) \ + VK_DEVICE_PFN(vkDestroySemaphore) \ + VK_DEVICE_PFN(vkDestroyShaderModule) \ + VK_DEVICE_PFN(vkDeviceWaitIdle) \ + VK_DEVICE_PFN(vkEndCommandBuffer) \ + VK_DEVICE_PFN(vkFlushMappedMemoryRanges) \ + VK_DEVICE_PFN(vkFreeCommandBuffers) \ + VK_DEVICE_PFN(vkFreeDescriptorSets) \ + VK_DEVICE_PFN(vkFreeMemory) \ + VK_DEVICE_PFN(vkGetBufferMemoryRequirements) \ + VK_DEVICE_PFN(vkGetDeviceMemoryCommitment) \ + VK_DEVICE_PFN(vkGetDeviceQueue) \ + VK_DEVICE_PFN(vkGetEventStatus) \ + VK_DEVICE_PFN(vkGetFenceStatus) \ + VK_DEVICE_PFN(vkGetImageMemoryRequirements) \ + VK_DEVICE_PFN(vkGetImageSparseMemoryRequirements) \ + VK_DEVICE_PFN(vkGetImageSubresourceLayout) \ + VK_DEVICE_PFN(vkGetPipelineCacheData) \ + VK_DEVICE_PFN(vkGetQueryPoolResults) \ + VK_DEVICE_PFN(vkGetRenderAreaGranularity) \ + VK_DEVICE_PFN(vkInvalidateMappedMemoryRanges) \ + VK_DEVICE_PFN(vkMapMemory) \ + VK_DEVICE_PFN(vkMergePipelineCaches) \ + VK_DEVICE_PFN(vkQueueBindSparse) \ + VK_DEVICE_PFN(vkQueueSubmit) \ + VK_DEVICE_PFN(vkQueueWaitIdle) \ + VK_DEVICE_PFN(vkResetCommandBuffer) \ + VK_DEVICE_PFN(vkResetCommandPool) \ + VK_DEVICE_PFN(vkResetDescriptorPool) \ + VK_DEVICE_PFN(vkResetEvent) \ + VK_DEVICE_PFN(vkResetFences) \ + VK_DEVICE_PFN(vkSetEvent) \ + VK_DEVICE_PFN(vkUnmapMemory) \ + VK_DEVICE_PFN(vkUpdateDescriptorSets) \ + VK_DEVICE_PFN(vkWaitForFences) + +#define DECLARE_VK_PFN(name) PFN_##name name; + +struct vulkan_ops +{ +#define VK_INSTANCE_PFN DECLARE_VK_PFN +#define VK_DEVICE_PFN DECLARE_VK_PFN + VK_DEVICE_FUNCS() + VK_INSTANCE_FUNCS() +#undef VK_INSTANCE_PFN +#undef VK_DEVICE_PFN + + PFN_vkCreateInstance vkCreateInstance; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; +}; + +struct wined3d_vk_info +{ + VkInstance instance; + struct vulkan_ops vk_ops; +}; + +#define VK_CALL(f) (vk_info->vk_ops.f) + +#endif /* __WINE_WINED3D_VK */