From 6eacdf38e29dcf2d87cb91374fd46987603f5594 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Fri, 9 Mar 2018 08:48:48 -0800 Subject: [PATCH] winevulkan: Implement vkCreateDevice. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Roderick Colenbrander Signed-off-by: Józef Kucia Signed-off-by: Alexandre Julliard --- dlls/winevulkan/make_vulkan | 39 ++++- dlls/winevulkan/vulkan.c | 70 ++++++++- dlls/winevulkan/vulkan_private.h | 8 + dlls/winevulkan/vulkan_thunks.c | 6 - dlls/winevulkan/vulkan_thunks.h | 248 +++++++++++++++++++++++++++++++ dlls/winex11.drv/vulkan.c | 9 ++ include/wine/vulkan_driver.h | 3 +- 7 files changed, 371 insertions(+), 12 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index f11cc152c49..4028ad32139 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -71,7 +71,7 @@ WINE_VULKAN_THUNKS_H = "vulkan_thunks.h" # Functions part of our winevulkan graphics driver interface. # DRIVER_VERSION should be bumped on any change to driver interface # in FUNCTION_OVERRIDES -DRIVER_VERSION = 1 +DRIVER_VERSION = 2 # Table of functions for which we have a special implementation. # This are regular device / instance functions for which we need @@ -88,9 +88,13 @@ FUNCTION_OVERRIDES = { "vkGetInstanceProcAddr": {"dispatch" : False, "driver" : True, "thunk" : False}, # Instance functions + "vkCreateDevice" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkDestroyInstance" : {"dispatch" : True, "driver" : True, "thunk" : False }, "vkEnumerateDeviceExtensionProperties" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkEnumeratePhysicalDevices" : {"dispatch" : True, "driver" : False, "thunk" : False}, + + # Device functions + "vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : True}, } @@ -351,9 +355,6 @@ class VkFunction(object): def needs_stub(self): """ Temporary function to limit script hacks until more code is implemented. """ - if self.name == "vkCreateDevice": - return True - if self.params[0].type != "VkPhysicalDevice": return True @@ -1791,6 +1792,19 @@ class VkGenerator(object): f.write(struct.definition(align=False, conv=True, postfix="_host")) f.write("\n") + f.write("/* For use by vkDevice and children */\n") + f.write("struct vulkan_device_funcs\n{\n") + for vk_func in self.registry.device_funcs: + if not vk_func.is_required(): + continue + + if not vk_func.needs_dispatch() or vk_func.is_driver_func(): + LOGGER.debug("skipping {0} in vulkan_device_funcs".format(vk_func.name)) + continue + + f.write(" {0};\n".format(vk_func.pfn(conv=False))) + f.write("};\n\n") + f.write("/* For use by vkInstance and children */\n") f.write("struct vulkan_instance_funcs\n{\n") for vk_func in self.registry.instance_funcs: @@ -1811,6 +1825,23 @@ class VkGenerator(object): f.write(" {0};\n".format(vk_func.pfn(conv=False))) f.write("};\n\n") + f.write("#define ALL_VK_DEVICE_FUNCS() \\\n") + first = True + for vk_func in self.registry.device_funcs: + if not vk_func.is_required(): + continue + + if not vk_func.needs_dispatch() or vk_func.is_driver_func(): + LOGGER.debug("skipping {0} in ALL_VK_DEVICE_FUNCS".format(vk_func.name)) + continue + + if first: + f.write(" USE_VK_FUNC({0})".format(vk_func.name)) + first = False + else: + f.write(" \\\n USE_VK_FUNC({0})".format(vk_func.name)) + f.write("\n\n") + f.write("#define ALL_VK_INSTANCE_FUNCS() \\\n") first = True for vk_func in self.registry.instance_funcs: diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 12d56f5b513..83c94eb856a 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -42,6 +42,22 @@ static void *wine_vk_get_global_proc_addr(const char *name); static const struct vulkan_funcs *vk_funcs = NULL; +/* Helper function used for freeing a device structure. This function supports full + * and partial object cleanups and can thus be used for vkCreateDevice failures. + */ +static void wine_vk_device_free(struct VkDevice_T *device) +{ + if (!device) + return; + + if (device->device && device->funcs.p_vkDestroyDevice) + { + device->funcs.p_vkDestroyDevice(device->device, NULL /* pAllocator */); + } + + heap_free(device); +} + static BOOL wine_vk_init(void) { HDC hdc = GetDC(0); @@ -146,6 +162,58 @@ static void wine_vk_instance_free(struct VkInstance_T *instance) heap_free(instance); } +VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev, + const VkDeviceCreateInfo *create_info, + const VkAllocationCallbacks *allocator, VkDevice *device) +{ + struct VkDevice_T *object = NULL; + VkResult res; + + TRACE("%p %p %p %p\n", phys_dev, create_info, allocator, device); + + if (allocator) + { + FIXME("Support for allocation callbacks not implemented yet\n"); + } + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + object->base.loader_magic = VULKAN_ICD_MAGIC_VALUE; + + /* At least for now we can directly pass create_info through. All extensions we report + * should be compatible. In addition the loader is supposed to sanitize values e.g. layers. + */ + res = phys_dev->instance->funcs.p_vkCreateDevice(phys_dev->phys_dev, + create_info, NULL /* allocator */, &object->device); + if (res != VK_SUCCESS) + { + ERR("Failed to create device\n"); + goto err; + } + + object->phys_dev = phys_dev; + + /* Just load all function pointers we are aware off. The loader takes care of filtering. + * We use vkGetDeviceProcAddr as opposed to vkGetInstanceProcAddr for efficiency reasons + * as functions pass through fewer dispatch tables within the loader. + */ +#define USE_VK_FUNC(name) \ + object->funcs.p_##name = (void *)vk_funcs->p_vkGetDeviceProcAddr(object->device, #name); \ + if (object->funcs.p_##name == NULL) \ + TRACE("Not found %s\n", #name); + ALL_VK_DEVICE_FUNCS() +#undef USE_VK_FUNC + + *device = object; + return VK_SUCCESS; + +err: + wine_vk_device_free(object); + return res; +} + static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *instance) { @@ -178,7 +246,7 @@ static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_ * ICD may support. */ #define USE_VK_FUNC(name) \ - object->funcs.p_##name = (void*)vk_funcs->p_vkGetInstanceProcAddr(object->instance, #name); + object->funcs.p_##name = (void *)vk_funcs->p_vkGetInstanceProcAddr(object->instance, #name); ALL_VK_INSTANCE_FUNCS() #undef USE_VK_FUNC diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 8ef4b924a2b..897c1e1418d 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -48,6 +48,14 @@ struct wine_vk_base UINT_PTR loader_magic; }; +struct VkDevice_T +{ + struct wine_vk_base base; + struct vulkan_device_funcs funcs; + struct VkPhysicalDevice_T *phys_dev; /* parent */ + VkDevice device; /* native device */ +}; + struct VkInstance_T { struct wine_vk_base base; diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 5fdbffaa62a..f02ee3e2bf6 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -467,12 +467,6 @@ static VkResult WINAPI wine_vkCreateDescriptorSetLayout(VkDevice device, const V return VK_ERROR_OUT_OF_HOST_MEMORY; } -static VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) -{ - FIXME("stub: %p, %p, %p, %p\n", physicalDevice, pCreateInfo, pAllocator, pDevice); - return VK_ERROR_OUT_OF_HOST_MEMORY; -} - static VkResult WINAPI wine_vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) { FIXME("stub: %p, %p, %p, %p\n", device, pCreateInfo, pAllocator, pEvent); diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 25fd9a8b67d..f98307c9c96 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -13,6 +13,7 @@ void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN; void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN; /* Functions for which we have custom implementations outside of the thunks. */ +VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) DECLSPEC_HIDDEN; void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN; @@ -164,6 +165,131 @@ typedef struct VkPhysicalDeviceProperties_host } VkPhysicalDeviceProperties_host; +/* For use by vkDevice and children */ +struct vulkan_device_funcs +{ + VkResult (*p_vkAllocateCommandBuffers)(VkDevice, const VkCommandBufferAllocateInfo *, VkCommandBuffer *); + VkResult (*p_vkAllocateDescriptorSets)(VkDevice, const VkDescriptorSetAllocateInfo *, VkDescriptorSet *); + VkResult (*p_vkAllocateMemory)(VkDevice, const VkMemoryAllocateInfo *, const VkAllocationCallbacks *, VkDeviceMemory *); + VkResult (*p_vkBeginCommandBuffer)(VkCommandBuffer, const VkCommandBufferBeginInfo *); + VkResult (*p_vkBindBufferMemory)(VkDevice, VkBuffer, VkDeviceMemory, VkDeviceSize); + VkResult (*p_vkBindImageMemory)(VkDevice, VkImage, VkDeviceMemory, VkDeviceSize); + void (*p_vkCmdBeginQuery)(VkCommandBuffer, VkQueryPool, uint32_t, VkQueryControlFlags); + void (*p_vkCmdBeginRenderPass)(VkCommandBuffer, const VkRenderPassBeginInfo *, VkSubpassContents); + void (*p_vkCmdBindDescriptorSets)(VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t, const VkDescriptorSet *, uint32_t, const uint32_t *); + void (*p_vkCmdBindIndexBuffer)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkIndexType); + void (*p_vkCmdBindPipeline)(VkCommandBuffer, VkPipelineBindPoint, VkPipeline); + void (*p_vkCmdBindVertexBuffers)(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer *, const VkDeviceSize *); + void (*p_vkCmdBlitImage)(VkCommandBuffer, VkImage, VkImageLayout, VkImage, VkImageLayout, uint32_t, const VkImageBlit *, VkFilter); + void (*p_vkCmdClearAttachments)(VkCommandBuffer, uint32_t, const VkClearAttachment *, uint32_t, const VkClearRect *); + void (*p_vkCmdClearColorImage)(VkCommandBuffer, VkImage, VkImageLayout, const VkClearColorValue *, uint32_t, const VkImageSubresourceRange *); + void (*p_vkCmdClearDepthStencilImage)(VkCommandBuffer, VkImage, VkImageLayout, const VkClearDepthStencilValue *, uint32_t, const VkImageSubresourceRange *); + void (*p_vkCmdCopyBuffer)(VkCommandBuffer, VkBuffer, VkBuffer, uint32_t, const VkBufferCopy *); + void (*p_vkCmdCopyBufferToImage)(VkCommandBuffer, VkBuffer, VkImage, VkImageLayout, uint32_t, const VkBufferImageCopy *); + void (*p_vkCmdCopyImage)(VkCommandBuffer, VkImage, VkImageLayout, VkImage, VkImageLayout, uint32_t, const VkImageCopy *); + void (*p_vkCmdCopyImageToBuffer)(VkCommandBuffer, VkImage, VkImageLayout, VkBuffer, uint32_t, const VkBufferImageCopy *); + void (*p_vkCmdCopyQueryPoolResults)(VkCommandBuffer, VkQueryPool, uint32_t, uint32_t, VkBuffer, VkDeviceSize, VkDeviceSize, VkQueryResultFlags); + void (*p_vkCmdDispatch)(VkCommandBuffer, uint32_t, uint32_t, uint32_t); + void (*p_vkCmdDispatchIndirect)(VkCommandBuffer, VkBuffer, VkDeviceSize); + void (*p_vkCmdDraw)(VkCommandBuffer, uint32_t, uint32_t, uint32_t, uint32_t); + void (*p_vkCmdDrawIndexed)(VkCommandBuffer, uint32_t, uint32_t, uint32_t, int32_t, uint32_t); + void (*p_vkCmdDrawIndexedIndirect)(VkCommandBuffer, VkBuffer, VkDeviceSize, uint32_t, uint32_t); + void (*p_vkCmdDrawIndirect)(VkCommandBuffer, VkBuffer, VkDeviceSize, uint32_t, uint32_t); + void (*p_vkCmdEndQuery)(VkCommandBuffer, VkQueryPool, uint32_t); + void (*p_vkCmdEndRenderPass)(VkCommandBuffer); + void (*p_vkCmdExecuteCommands)(VkCommandBuffer, uint32_t, const VkCommandBuffer *); + void (*p_vkCmdFillBuffer)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkDeviceSize, uint32_t); + void (*p_vkCmdNextSubpass)(VkCommandBuffer, VkSubpassContents); + void (*p_vkCmdPipelineBarrier)(VkCommandBuffer, VkPipelineStageFlags, VkPipelineStageFlags, VkDependencyFlags, uint32_t, const VkMemoryBarrier *, uint32_t, const VkBufferMemoryBarrier *, uint32_t, const VkImageMemoryBarrier *); + void (*p_vkCmdPushConstants)(VkCommandBuffer, VkPipelineLayout, VkShaderStageFlags, uint32_t, uint32_t, const void *); + void (*p_vkCmdResetEvent)(VkCommandBuffer, VkEvent, VkPipelineStageFlags); + void (*p_vkCmdResetQueryPool)(VkCommandBuffer, VkQueryPool, uint32_t, uint32_t); + void (*p_vkCmdResolveImage)(VkCommandBuffer, VkImage, VkImageLayout, VkImage, VkImageLayout, uint32_t, const VkImageResolve *); + void (*p_vkCmdSetBlendConstants)(VkCommandBuffer, const float[4]); + void (*p_vkCmdSetDepthBias)(VkCommandBuffer, float, float, float); + void (*p_vkCmdSetDepthBounds)(VkCommandBuffer, float, float); + void (*p_vkCmdSetEvent)(VkCommandBuffer, VkEvent, VkPipelineStageFlags); + void (*p_vkCmdSetLineWidth)(VkCommandBuffer, float); + void (*p_vkCmdSetScissor)(VkCommandBuffer, uint32_t, uint32_t, const VkRect2D *); + void (*p_vkCmdSetStencilCompareMask)(VkCommandBuffer, VkStencilFaceFlags, uint32_t); + void (*p_vkCmdSetStencilReference)(VkCommandBuffer, VkStencilFaceFlags, uint32_t); + void (*p_vkCmdSetStencilWriteMask)(VkCommandBuffer, VkStencilFaceFlags, uint32_t); + void (*p_vkCmdSetViewport)(VkCommandBuffer, uint32_t, uint32_t, const VkViewport *); + void (*p_vkCmdUpdateBuffer)(VkCommandBuffer, VkBuffer, VkDeviceSize, VkDeviceSize, const void *); + void (*p_vkCmdWaitEvents)(VkCommandBuffer, uint32_t, const VkEvent *, VkPipelineStageFlags, VkPipelineStageFlags, uint32_t, const VkMemoryBarrier *, uint32_t, const VkBufferMemoryBarrier *, uint32_t, const VkImageMemoryBarrier *); + void (*p_vkCmdWriteTimestamp)(VkCommandBuffer, VkPipelineStageFlagBits, VkQueryPool, uint32_t); + VkResult (*p_vkCreateBuffer)(VkDevice, const VkBufferCreateInfo *, const VkAllocationCallbacks *, VkBuffer *); + VkResult (*p_vkCreateBufferView)(VkDevice, const VkBufferViewCreateInfo *, const VkAllocationCallbacks *, VkBufferView *); + VkResult (*p_vkCreateCommandPool)(VkDevice, const VkCommandPoolCreateInfo *, const VkAllocationCallbacks *, VkCommandPool *); + VkResult (*p_vkCreateComputePipelines)(VkDevice, VkPipelineCache, uint32_t, const VkComputePipelineCreateInfo *, const VkAllocationCallbacks *, VkPipeline *); + VkResult (*p_vkCreateDescriptorPool)(VkDevice, const VkDescriptorPoolCreateInfo *, const VkAllocationCallbacks *, VkDescriptorPool *); + VkResult (*p_vkCreateDescriptorSetLayout)(VkDevice, const VkDescriptorSetLayoutCreateInfo *, const VkAllocationCallbacks *, VkDescriptorSetLayout *); + VkResult (*p_vkCreateEvent)(VkDevice, const VkEventCreateInfo *, const VkAllocationCallbacks *, VkEvent *); + VkResult (*p_vkCreateFence)(VkDevice, const VkFenceCreateInfo *, const VkAllocationCallbacks *, VkFence *); + VkResult (*p_vkCreateFramebuffer)(VkDevice, const VkFramebufferCreateInfo *, const VkAllocationCallbacks *, VkFramebuffer *); + VkResult (*p_vkCreateGraphicsPipelines)(VkDevice, VkPipelineCache, uint32_t, const VkGraphicsPipelineCreateInfo *, const VkAllocationCallbacks *, VkPipeline *); + VkResult (*p_vkCreateImage)(VkDevice, const VkImageCreateInfo *, const VkAllocationCallbacks *, VkImage *); + VkResult (*p_vkCreateImageView)(VkDevice, const VkImageViewCreateInfo *, const VkAllocationCallbacks *, VkImageView *); + VkResult (*p_vkCreatePipelineCache)(VkDevice, const VkPipelineCacheCreateInfo *, const VkAllocationCallbacks *, VkPipelineCache *); + VkResult (*p_vkCreatePipelineLayout)(VkDevice, const VkPipelineLayoutCreateInfo *, const VkAllocationCallbacks *, VkPipelineLayout *); + VkResult (*p_vkCreateQueryPool)(VkDevice, const VkQueryPoolCreateInfo *, const VkAllocationCallbacks *, VkQueryPool *); + VkResult (*p_vkCreateRenderPass)(VkDevice, const VkRenderPassCreateInfo *, const VkAllocationCallbacks *, VkRenderPass *); + VkResult (*p_vkCreateSampler)(VkDevice, const VkSamplerCreateInfo *, const VkAllocationCallbacks *, VkSampler *); + VkResult (*p_vkCreateSemaphore)(VkDevice, const VkSemaphoreCreateInfo *, const VkAllocationCallbacks *, VkSemaphore *); + VkResult (*p_vkCreateShaderModule)(VkDevice, const VkShaderModuleCreateInfo *, const VkAllocationCallbacks *, VkShaderModule *); + void (*p_vkDestroyBuffer)(VkDevice, VkBuffer, const VkAllocationCallbacks *); + void (*p_vkDestroyBufferView)(VkDevice, VkBufferView, const VkAllocationCallbacks *); + void (*p_vkDestroyCommandPool)(VkDevice, VkCommandPool, const VkAllocationCallbacks *); + void (*p_vkDestroyDescriptorPool)(VkDevice, VkDescriptorPool, const VkAllocationCallbacks *); + void (*p_vkDestroyDescriptorSetLayout)(VkDevice, VkDescriptorSetLayout, const VkAllocationCallbacks *); + void (*p_vkDestroyDevice)(VkDevice, const VkAllocationCallbacks *); + void (*p_vkDestroyEvent)(VkDevice, VkEvent, const VkAllocationCallbacks *); + void (*p_vkDestroyFence)(VkDevice, VkFence, const VkAllocationCallbacks *); + void (*p_vkDestroyFramebuffer)(VkDevice, VkFramebuffer, const VkAllocationCallbacks *); + void (*p_vkDestroyImage)(VkDevice, VkImage, const VkAllocationCallbacks *); + void (*p_vkDestroyImageView)(VkDevice, VkImageView, const VkAllocationCallbacks *); + void (*p_vkDestroyPipeline)(VkDevice, VkPipeline, const VkAllocationCallbacks *); + void (*p_vkDestroyPipelineCache)(VkDevice, VkPipelineCache, const VkAllocationCallbacks *); + void (*p_vkDestroyPipelineLayout)(VkDevice, VkPipelineLayout, const VkAllocationCallbacks *); + void (*p_vkDestroyQueryPool)(VkDevice, VkQueryPool, const VkAllocationCallbacks *); + void (*p_vkDestroyRenderPass)(VkDevice, VkRenderPass, const VkAllocationCallbacks *); + void (*p_vkDestroySampler)(VkDevice, VkSampler, const VkAllocationCallbacks *); + void (*p_vkDestroySemaphore)(VkDevice, VkSemaphore, const VkAllocationCallbacks *); + void (*p_vkDestroyShaderModule)(VkDevice, VkShaderModule, const VkAllocationCallbacks *); + VkResult (*p_vkDeviceWaitIdle)(VkDevice); + VkResult (*p_vkEndCommandBuffer)(VkCommandBuffer); + VkResult (*p_vkFlushMappedMemoryRanges)(VkDevice, uint32_t, const VkMappedMemoryRange *); + void (*p_vkFreeCommandBuffers)(VkDevice, VkCommandPool, uint32_t, const VkCommandBuffer *); + VkResult (*p_vkFreeDescriptorSets)(VkDevice, VkDescriptorPool, uint32_t, const VkDescriptorSet *); + void (*p_vkFreeMemory)(VkDevice, VkDeviceMemory, const VkAllocationCallbacks *); + void (*p_vkGetBufferMemoryRequirements)(VkDevice, VkBuffer, VkMemoryRequirements *); + void (*p_vkGetDeviceMemoryCommitment)(VkDevice, VkDeviceMemory, VkDeviceSize *); + void (*p_vkGetDeviceQueue)(VkDevice, uint32_t, uint32_t, VkQueue *); + VkResult (*p_vkGetEventStatus)(VkDevice, VkEvent); + VkResult (*p_vkGetFenceStatus)(VkDevice, VkFence); + void (*p_vkGetImageMemoryRequirements)(VkDevice, VkImage, VkMemoryRequirements *); + void (*p_vkGetImageSparseMemoryRequirements)(VkDevice, VkImage, uint32_t *, VkSparseImageMemoryRequirements *); + void (*p_vkGetImageSubresourceLayout)(VkDevice, VkImage, const VkImageSubresource *, VkSubresourceLayout *); + VkResult (*p_vkGetPipelineCacheData)(VkDevice, VkPipelineCache, size_t *, void *); + VkResult (*p_vkGetQueryPoolResults)(VkDevice, VkQueryPool, uint32_t, uint32_t, size_t, void *, VkDeviceSize, VkQueryResultFlags); + void (*p_vkGetRenderAreaGranularity)(VkDevice, VkRenderPass, VkExtent2D *); + VkResult (*p_vkInvalidateMappedMemoryRanges)(VkDevice, uint32_t, const VkMappedMemoryRange *); + VkResult (*p_vkMapMemory)(VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void **); + VkResult (*p_vkMergePipelineCaches)(VkDevice, VkPipelineCache, uint32_t, const VkPipelineCache *); + VkResult (*p_vkQueueBindSparse)(VkQueue, uint32_t, const VkBindSparseInfo *, VkFence); + VkResult (*p_vkQueueSubmit)(VkQueue, uint32_t, const VkSubmitInfo *, VkFence); + VkResult (*p_vkQueueWaitIdle)(VkQueue); + VkResult (*p_vkResetCommandBuffer)(VkCommandBuffer, VkCommandBufferResetFlags); + VkResult (*p_vkResetCommandPool)(VkDevice, VkCommandPool, VkCommandPoolResetFlags); + VkResult (*p_vkResetDescriptorPool)(VkDevice, VkDescriptorPool, VkDescriptorPoolResetFlags); + VkResult (*p_vkResetEvent)(VkDevice, VkEvent); + VkResult (*p_vkResetFences)(VkDevice, uint32_t, const VkFence *); + VkResult (*p_vkSetEvent)(VkDevice, VkEvent); + void (*p_vkUnmapMemory)(VkDevice, VkDeviceMemory); + void (*p_vkUpdateDescriptorSets)(VkDevice, uint32_t, const VkWriteDescriptorSet *, uint32_t, const VkCopyDescriptorSet *); + VkResult (*p_vkWaitForFences)(VkDevice, uint32_t, const VkFence *, VkBool32, uint64_t); +}; + /* For use by vkInstance and children */ struct vulkan_instance_funcs { @@ -192,6 +318,128 @@ struct vulkan_instance_funcs void (*p_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice, VkFormat, VkImageType, VkSampleCountFlagBits, VkImageUsageFlags, VkImageTiling, uint32_t *, VkSparseImageFormatProperties *); }; +#define ALL_VK_DEVICE_FUNCS() \ + USE_VK_FUNC(vkAllocateCommandBuffers) \ + USE_VK_FUNC(vkAllocateDescriptorSets) \ + USE_VK_FUNC(vkAllocateMemory) \ + USE_VK_FUNC(vkBeginCommandBuffer) \ + USE_VK_FUNC(vkBindBufferMemory) \ + USE_VK_FUNC(vkBindImageMemory) \ + USE_VK_FUNC(vkCmdBeginQuery) \ + USE_VK_FUNC(vkCmdBeginRenderPass) \ + USE_VK_FUNC(vkCmdBindDescriptorSets) \ + USE_VK_FUNC(vkCmdBindIndexBuffer) \ + USE_VK_FUNC(vkCmdBindPipeline) \ + USE_VK_FUNC(vkCmdBindVertexBuffers) \ + USE_VK_FUNC(vkCmdBlitImage) \ + USE_VK_FUNC(vkCmdClearAttachments) \ + USE_VK_FUNC(vkCmdClearColorImage) \ + USE_VK_FUNC(vkCmdClearDepthStencilImage) \ + USE_VK_FUNC(vkCmdCopyBuffer) \ + USE_VK_FUNC(vkCmdCopyBufferToImage) \ + USE_VK_FUNC(vkCmdCopyImage) \ + USE_VK_FUNC(vkCmdCopyImageToBuffer) \ + USE_VK_FUNC(vkCmdCopyQueryPoolResults) \ + USE_VK_FUNC(vkCmdDispatch) \ + USE_VK_FUNC(vkCmdDispatchIndirect) \ + USE_VK_FUNC(vkCmdDraw) \ + USE_VK_FUNC(vkCmdDrawIndexed) \ + USE_VK_FUNC(vkCmdDrawIndexedIndirect) \ + USE_VK_FUNC(vkCmdDrawIndirect) \ + USE_VK_FUNC(vkCmdEndQuery) \ + USE_VK_FUNC(vkCmdEndRenderPass) \ + USE_VK_FUNC(vkCmdExecuteCommands) \ + USE_VK_FUNC(vkCmdFillBuffer) \ + USE_VK_FUNC(vkCmdNextSubpass) \ + USE_VK_FUNC(vkCmdPipelineBarrier) \ + USE_VK_FUNC(vkCmdPushConstants) \ + USE_VK_FUNC(vkCmdResetEvent) \ + USE_VK_FUNC(vkCmdResetQueryPool) \ + USE_VK_FUNC(vkCmdResolveImage) \ + USE_VK_FUNC(vkCmdSetBlendConstants) \ + USE_VK_FUNC(vkCmdSetDepthBias) \ + USE_VK_FUNC(vkCmdSetDepthBounds) \ + USE_VK_FUNC(vkCmdSetEvent) \ + USE_VK_FUNC(vkCmdSetLineWidth) \ + USE_VK_FUNC(vkCmdSetScissor) \ + USE_VK_FUNC(vkCmdSetStencilCompareMask) \ + USE_VK_FUNC(vkCmdSetStencilReference) \ + USE_VK_FUNC(vkCmdSetStencilWriteMask) \ + USE_VK_FUNC(vkCmdSetViewport) \ + USE_VK_FUNC(vkCmdUpdateBuffer) \ + USE_VK_FUNC(vkCmdWaitEvents) \ + USE_VK_FUNC(vkCmdWriteTimestamp) \ + USE_VK_FUNC(vkCreateBuffer) \ + USE_VK_FUNC(vkCreateBufferView) \ + USE_VK_FUNC(vkCreateCommandPool) \ + USE_VK_FUNC(vkCreateComputePipelines) \ + USE_VK_FUNC(vkCreateDescriptorPool) \ + USE_VK_FUNC(vkCreateDescriptorSetLayout) \ + USE_VK_FUNC(vkCreateEvent) \ + USE_VK_FUNC(vkCreateFence) \ + USE_VK_FUNC(vkCreateFramebuffer) \ + USE_VK_FUNC(vkCreateGraphicsPipelines) \ + USE_VK_FUNC(vkCreateImage) \ + USE_VK_FUNC(vkCreateImageView) \ + USE_VK_FUNC(vkCreatePipelineCache) \ + USE_VK_FUNC(vkCreatePipelineLayout) \ + USE_VK_FUNC(vkCreateQueryPool) \ + USE_VK_FUNC(vkCreateRenderPass) \ + USE_VK_FUNC(vkCreateSampler) \ + USE_VK_FUNC(vkCreateSemaphore) \ + USE_VK_FUNC(vkCreateShaderModule) \ + USE_VK_FUNC(vkDestroyBuffer) \ + USE_VK_FUNC(vkDestroyBufferView) \ + USE_VK_FUNC(vkDestroyCommandPool) \ + USE_VK_FUNC(vkDestroyDescriptorPool) \ + USE_VK_FUNC(vkDestroyDescriptorSetLayout) \ + USE_VK_FUNC(vkDestroyDevice) \ + USE_VK_FUNC(vkDestroyEvent) \ + USE_VK_FUNC(vkDestroyFence) \ + USE_VK_FUNC(vkDestroyFramebuffer) \ + USE_VK_FUNC(vkDestroyImage) \ + USE_VK_FUNC(vkDestroyImageView) \ + USE_VK_FUNC(vkDestroyPipeline) \ + USE_VK_FUNC(vkDestroyPipelineCache) \ + USE_VK_FUNC(vkDestroyPipelineLayout) \ + USE_VK_FUNC(vkDestroyQueryPool) \ + USE_VK_FUNC(vkDestroyRenderPass) \ + USE_VK_FUNC(vkDestroySampler) \ + USE_VK_FUNC(vkDestroySemaphore) \ + USE_VK_FUNC(vkDestroyShaderModule) \ + USE_VK_FUNC(vkDeviceWaitIdle) \ + USE_VK_FUNC(vkEndCommandBuffer) \ + USE_VK_FUNC(vkFlushMappedMemoryRanges) \ + USE_VK_FUNC(vkFreeCommandBuffers) \ + USE_VK_FUNC(vkFreeDescriptorSets) \ + USE_VK_FUNC(vkFreeMemory) \ + USE_VK_FUNC(vkGetBufferMemoryRequirements) \ + USE_VK_FUNC(vkGetDeviceMemoryCommitment) \ + USE_VK_FUNC(vkGetDeviceQueue) \ + USE_VK_FUNC(vkGetEventStatus) \ + USE_VK_FUNC(vkGetFenceStatus) \ + USE_VK_FUNC(vkGetImageMemoryRequirements) \ + USE_VK_FUNC(vkGetImageSparseMemoryRequirements) \ + USE_VK_FUNC(vkGetImageSubresourceLayout) \ + USE_VK_FUNC(vkGetPipelineCacheData) \ + USE_VK_FUNC(vkGetQueryPoolResults) \ + USE_VK_FUNC(vkGetRenderAreaGranularity) \ + USE_VK_FUNC(vkInvalidateMappedMemoryRanges) \ + USE_VK_FUNC(vkMapMemory) \ + USE_VK_FUNC(vkMergePipelineCaches) \ + USE_VK_FUNC(vkQueueBindSparse) \ + USE_VK_FUNC(vkQueueSubmit) \ + USE_VK_FUNC(vkQueueWaitIdle) \ + USE_VK_FUNC(vkResetCommandBuffer) \ + USE_VK_FUNC(vkResetCommandPool) \ + USE_VK_FUNC(vkResetDescriptorPool) \ + USE_VK_FUNC(vkResetEvent) \ + USE_VK_FUNC(vkResetFences) \ + USE_VK_FUNC(vkSetEvent) \ + USE_VK_FUNC(vkUnmapMemory) \ + USE_VK_FUNC(vkUpdateDescriptorSets) \ + USE_VK_FUNC(vkWaitForFences) + #define ALL_VK_INSTANCE_FUNCS() \ USE_VK_FUNC(vkCreateDevice)\ USE_VK_FUNC(vkEnumerateDeviceExtensionProperties)\ diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index c3fed9e58a7..c99ca66168e 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -36,6 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); +static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *); static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *); static BOOL wine_vk_init(void) @@ -51,6 +52,7 @@ static BOOL wine_vk_init(void) #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE; LOAD_FUNCPTR(vkCreateInstance) LOAD_FUNCPTR(vkDestroyInstance) +LOAD_FUNCPTR(vkGetDeviceProcAddr) LOAD_FUNCPTR(vkGetInstanceProcAddr) #undef LOAD_FUNCPTR @@ -116,6 +118,12 @@ static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_ return VK_SUCCESS; } +static void * X11DRV_vkGetDeviceProcAddr(VkDevice device, const char *name) +{ + TRACE("%p, %s\n", device, debugstr_a(name)); + return pvkGetDeviceProcAddr(device, name); +} + static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *name) { TRACE("%p, %s\n", instance, debugstr_a(name)); @@ -127,6 +135,7 @@ static const struct vulkan_funcs vulkan_funcs = X11DRV_vkCreateInstance, X11DRV_vkDestroyInstance, X11DRV_vkEnumerateInstanceExtensionProperties, + X11DRV_vkGetDeviceProcAddr, X11DRV_vkGetInstanceProcAddr }; diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 2e2abf9f026..8d69222e03c 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -4,7 +4,7 @@ #define __WINE_VULKAN_DRIVER_H /* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ -#define WINE_VULKAN_DRIVER_VERSION 1 +#define WINE_VULKAN_DRIVER_VERSION 2 struct vulkan_funcs { @@ -15,6 +15,7 @@ struct vulkan_funcs VkResult (*p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); void (*p_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); VkResult (*p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *); + void * (*p_vkGetDeviceProcAddr)(VkDevice, const char *); void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *); };