[PATCH 4/5] vulkan-1: Implement thunks for Vulkan Core functions.

Józef Kucia joseph.kucia at gmail.com
Tue Mar 27 17:51:06 CDT 2018


I wonder if we can simplify our Vulkan loader further. We could
potentially export all core Vulkan functions from winevulkan.dll with
the "wine_" prefix. The Vulkan loader documentation allows exporting
Vulkan functions from ICD under different names. It would allow us to
simply forward most of the functions directly to winevulkan.dll (even
in the spec file). The proposed solution would make our vulkan-1.dll
really minimal and simple, and would also avoid the race condition
mentioned in the comment below. Thoughts?

On Tue, Mar 27, 2018 at 9:00 AM, Roderick Colenbrander
<thunderbird2k at gmail.com> wrote:
> Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
> ---
>  dlls/vulkan-1/vulkan-1.spec | 304 ++++++++++++++++++++++----------------------
>  dlls/vulkan-1/vulkan.c      |  30 ++++-
>  dlls/winevulkan/make_vulkan |  79 +++++++++++-
>  3 files changed, 255 insertions(+), 158 deletions(-)
>
> diff --git a/dlls/vulkan-1/vulkan-1.spec b/dlls/vulkan-1/vulkan-1.spec
> index 088a3f23ac..5fed8850e8 100644
> --- a/dlls/vulkan-1/vulkan-1.spec
> +++ b/dlls/vulkan-1/vulkan-1.spec
> @@ -1,158 +1,158 @@
>  # Automatically generated from Vulkan vk.xml; DO NOT EDIT!
>
> -@ stub vkAcquireNextImageKHR
> -@ stub vkAllocateCommandBuffers
> -@ stub vkAllocateDescriptorSets
> -@ stub vkAllocateMemory
> -@ stub vkBeginCommandBuffer
> -@ stub vkBindBufferMemory
> -@ stub vkBindImageMemory
> -@ stub vkCmdBeginQuery
> -@ stub vkCmdBeginRenderPass
> -@ stub vkCmdBindDescriptorSets
> -@ stub vkCmdBindIndexBuffer
> -@ stub vkCmdBindPipeline
> -@ stub vkCmdBindVertexBuffers
> -@ stub vkCmdBlitImage
> -@ stub vkCmdClearAttachments
> -@ stub vkCmdClearColorImage
> -@ stub vkCmdClearDepthStencilImage
> -@ stub vkCmdCopyBuffer
> -@ stub vkCmdCopyBufferToImage
> -@ stub vkCmdCopyImage
> -@ stub vkCmdCopyImageToBuffer
> -@ stub vkCmdCopyQueryPoolResults
> -@ stub vkCmdDispatch
> -@ stub vkCmdDispatchIndirect
> -@ stub vkCmdDraw
> -@ stub vkCmdDrawIndexed
> -@ stub vkCmdDrawIndexedIndirect
> -@ stub vkCmdDrawIndirect
> -@ stub vkCmdEndQuery
> -@ stub vkCmdEndRenderPass
> -@ stub vkCmdExecuteCommands
> -@ stub vkCmdFillBuffer
> -@ stub vkCmdNextSubpass
> -@ stub vkCmdPipelineBarrier
> -@ stub vkCmdPushConstants
> -@ stub vkCmdResetEvent
> -@ stub vkCmdResetQueryPool
> -@ stub vkCmdResolveImage
> -@ stub vkCmdSetBlendConstants
> -@ stub vkCmdSetDepthBias
> -@ stub vkCmdSetDepthBounds
> -@ stub vkCmdSetEvent
> -@ stub vkCmdSetLineWidth
> -@ stub vkCmdSetScissor
> -@ stub vkCmdSetStencilCompareMask
> -@ stub vkCmdSetStencilReference
> -@ stub vkCmdSetStencilWriteMask
> -@ stub vkCmdSetViewport
> -@ stub vkCmdUpdateBuffer
> -@ stub vkCmdWaitEvents
> -@ stub vkCmdWriteTimestamp
> -@ stub vkCreateBuffer
> -@ stub vkCreateBufferView
> -@ stub vkCreateCommandPool
> -@ stub vkCreateComputePipelines
> -@ stub vkCreateDescriptorPool
> -@ stub vkCreateDescriptorSetLayout
> -@ stub vkCreateDevice
> -@ stub vkCreateDisplayModeKHR
> -@ stub vkCreateDisplayPlaneSurfaceKHR
> -@ stub vkCreateEvent
> -@ stub vkCreateFence
> -@ stub vkCreateFramebuffer
> -@ stub vkCreateGraphicsPipelines
> -@ stub vkCreateImage
> -@ stub vkCreateImageView
> +@ stdcall vkAcquireNextImageKHR(ptr int64 int64 int64 int64 ptr)
> +@ stdcall vkAllocateCommandBuffers(ptr ptr ptr)
> +@ stdcall vkAllocateDescriptorSets(ptr ptr ptr)
> +@ stdcall vkAllocateMemory(ptr ptr ptr ptr)
> +@ stdcall vkBeginCommandBuffer(ptr ptr)
> +@ stdcall vkBindBufferMemory(ptr int64 int64 int64)
> +@ stdcall vkBindImageMemory(ptr int64 int64 int64)
> +@ stdcall vkCmdBeginQuery(ptr int64 long long)
> +@ stdcall vkCmdBeginRenderPass(ptr ptr long)
> +@ stdcall vkCmdBindDescriptorSets(ptr long int64 long long ptr long ptr)
> +@ stdcall vkCmdBindIndexBuffer(ptr int64 int64 long)
> +@ stdcall vkCmdBindPipeline(ptr long int64)
> +@ stdcall vkCmdBindVertexBuffers(ptr long long ptr ptr)
> +@ stdcall vkCmdBlitImage(ptr int64 long int64 long long ptr long)
> +@ stdcall vkCmdClearAttachments(ptr long ptr long ptr)
> +@ stdcall vkCmdClearColorImage(ptr int64 long ptr long ptr)
> +@ stdcall vkCmdClearDepthStencilImage(ptr int64 long ptr long ptr)
> +@ stdcall vkCmdCopyBuffer(ptr int64 int64 long ptr)
> +@ stdcall vkCmdCopyBufferToImage(ptr int64 int64 long long ptr)
> +@ stdcall vkCmdCopyImage(ptr int64 long int64 long long ptr)
> +@ stdcall vkCmdCopyImageToBuffer(ptr int64 long int64 long ptr)
> +@ stdcall vkCmdCopyQueryPoolResults(ptr int64 long long int64 int64 int64 long)
> +@ stdcall vkCmdDispatch(ptr long long long)
> +@ stdcall vkCmdDispatchIndirect(ptr int64 int64)
> +@ stdcall vkCmdDraw(ptr long long long long)
> +@ stdcall vkCmdDrawIndexed(ptr long long long long long)
> +@ stdcall vkCmdDrawIndexedIndirect(ptr int64 int64 long long)
> +@ stdcall vkCmdDrawIndirect(ptr int64 int64 long long)
> +@ stdcall vkCmdEndQuery(ptr int64 long)
> +@ stdcall vkCmdEndRenderPass(ptr)
> +@ stdcall vkCmdExecuteCommands(ptr long ptr)
> +@ stdcall vkCmdFillBuffer(ptr int64 int64 int64 long)
> +@ stdcall vkCmdNextSubpass(ptr long)
> +@ stdcall vkCmdPipelineBarrier(ptr long long long long ptr long ptr long ptr)
> +@ stdcall vkCmdPushConstants(ptr int64 long long long ptr)
> +@ stdcall vkCmdResetEvent(ptr int64 long)
> +@ stdcall vkCmdResetQueryPool(ptr int64 long long)
> +@ stdcall vkCmdResolveImage(ptr int64 long int64 long long ptr)
> +@ stdcall vkCmdSetBlendConstants(ptr ptr)
> +@ stdcall vkCmdSetDepthBias(ptr float float float)
> +@ stdcall vkCmdSetDepthBounds(ptr float float)
> +@ stdcall vkCmdSetEvent(ptr int64 long)
> +@ stdcall vkCmdSetLineWidth(ptr float)
> +@ stdcall vkCmdSetScissor(ptr long long ptr)
> +@ stdcall vkCmdSetStencilCompareMask(ptr long long)
> +@ stdcall vkCmdSetStencilReference(ptr long long)
> +@ stdcall vkCmdSetStencilWriteMask(ptr long long)
> +@ stdcall vkCmdSetViewport(ptr long long ptr)
> +@ stdcall vkCmdUpdateBuffer(ptr int64 int64 int64 ptr)
> +@ stdcall vkCmdWaitEvents(ptr long ptr long long long ptr long ptr long ptr)
> +@ stdcall vkCmdWriteTimestamp(ptr long int64 long)
> +@ stdcall vkCreateBuffer(ptr ptr ptr ptr)
> +@ stdcall vkCreateBufferView(ptr ptr ptr ptr)
> +@ stdcall vkCreateCommandPool(ptr ptr ptr ptr)
> +@ stdcall vkCreateComputePipelines(ptr int64 long ptr ptr ptr)
> +@ stdcall vkCreateDescriptorPool(ptr ptr ptr ptr)
> +@ stdcall vkCreateDescriptorSetLayout(ptr ptr ptr ptr)
> +@ stdcall vkCreateDevice(ptr ptr ptr ptr)
> +@ stdcall vkCreateDisplayModeKHR(ptr int64 ptr ptr ptr)
> +@ stdcall vkCreateDisplayPlaneSurfaceKHR(ptr ptr ptr ptr)
> +@ stdcall vkCreateEvent(ptr ptr ptr ptr)
> +@ stdcall vkCreateFence(ptr ptr ptr ptr)
> +@ stdcall vkCreateFramebuffer(ptr ptr ptr ptr)
> +@ stdcall vkCreateGraphicsPipelines(ptr int64 long ptr ptr ptr)
> +@ stdcall vkCreateImage(ptr ptr ptr ptr)
> +@ stdcall vkCreateImageView(ptr ptr ptr ptr)
>  @ stdcall vkCreateInstance(ptr ptr ptr)
> -@ stub vkCreatePipelineCache
> -@ stub vkCreatePipelineLayout
> -@ stub vkCreateQueryPool
> -@ stub vkCreateRenderPass
> -@ stub vkCreateSampler
> -@ stub vkCreateSemaphore
> -@ stub vkCreateShaderModule
> -@ stub vkCreateSwapchainKHR
> -@ stub vkCreateWin32SurfaceKHR
> -@ stub vkDestroyBuffer
> -@ stub vkDestroyBufferView
> -@ stub vkDestroyCommandPool
> -@ stub vkDestroyDescriptorPool
> -@ stub vkDestroyDescriptorSetLayout
> -@ stub vkDestroyDevice
> -@ stub vkDestroyEvent
> -@ stub vkDestroyFence
> -@ stub vkDestroyFramebuffer
> -@ stub vkDestroyImage
> -@ stub vkDestroyImageView
> -@ stub vkDestroyInstance
> -@ stub vkDestroyPipeline
> -@ stub vkDestroyPipelineCache
> -@ stub vkDestroyPipelineLayout
> -@ stub vkDestroyQueryPool
> -@ stub vkDestroyRenderPass
> -@ stub vkDestroySampler
> -@ stub vkDestroySemaphore
> -@ stub vkDestroyShaderModule
> -@ stub vkDestroySurfaceKHR
> -@ stub vkDestroySwapchainKHR
> -@ stub vkDeviceWaitIdle
> -@ stub vkEndCommandBuffer
> -@ stub vkEnumerateDeviceExtensionProperties
> -@ stub vkEnumerateDeviceLayerProperties
> +@ stdcall vkCreatePipelineCache(ptr ptr ptr ptr)
> +@ stdcall vkCreatePipelineLayout(ptr ptr ptr ptr)
> +@ stdcall vkCreateQueryPool(ptr ptr ptr ptr)
> +@ stdcall vkCreateRenderPass(ptr ptr ptr ptr)
> +@ stdcall vkCreateSampler(ptr ptr ptr ptr)
> +@ stdcall vkCreateSemaphore(ptr ptr ptr ptr)
> +@ stdcall vkCreateShaderModule(ptr ptr ptr ptr)
> +@ stdcall vkCreateSwapchainKHR(ptr ptr ptr ptr)
> +@ stdcall vkCreateWin32SurfaceKHR(ptr ptr ptr ptr)
> +@ stdcall vkDestroyBuffer(ptr int64 ptr)
> +@ stdcall vkDestroyBufferView(ptr int64 ptr)
> +@ stdcall vkDestroyCommandPool(ptr int64 ptr)
> +@ stdcall vkDestroyDescriptorPool(ptr int64 ptr)
> +@ stdcall vkDestroyDescriptorSetLayout(ptr int64 ptr)
> +@ stdcall vkDestroyDevice(ptr ptr)
> +@ stdcall vkDestroyEvent(ptr int64 ptr)
> +@ stdcall vkDestroyFence(ptr int64 ptr)
> +@ stdcall vkDestroyFramebuffer(ptr int64 ptr)
> +@ stdcall vkDestroyImage(ptr int64 ptr)
> +@ stdcall vkDestroyImageView(ptr int64 ptr)
> +@ stdcall vkDestroyInstance(ptr ptr)
> +@ stdcall vkDestroyPipeline(ptr int64 ptr)
> +@ stdcall vkDestroyPipelineCache(ptr int64 ptr)
> +@ stdcall vkDestroyPipelineLayout(ptr int64 ptr)
> +@ stdcall vkDestroyQueryPool(ptr int64 ptr)
> +@ stdcall vkDestroyRenderPass(ptr int64 ptr)
> +@ stdcall vkDestroySampler(ptr int64 ptr)
> +@ stdcall vkDestroySemaphore(ptr int64 ptr)
> +@ stdcall vkDestroyShaderModule(ptr int64 ptr)
> +@ stdcall vkDestroySurfaceKHR(ptr int64 ptr)
> +@ stdcall vkDestroySwapchainKHR(ptr int64 ptr)
> +@ stdcall vkDeviceWaitIdle(ptr)
> +@ stdcall vkEndCommandBuffer(ptr)
> +@ stdcall vkEnumerateDeviceExtensionProperties(ptr str ptr ptr)
> +@ stdcall vkEnumerateDeviceLayerProperties(ptr ptr ptr)
>  @ stdcall vkEnumerateInstanceExtensionProperties(str ptr ptr)
>  @ stdcall vkEnumerateInstanceLayerProperties(ptr ptr)
> -@ stub vkEnumeratePhysicalDevices
> -@ stub vkFlushMappedMemoryRanges
> -@ stub vkFreeCommandBuffers
> -@ stub vkFreeDescriptorSets
> -@ stub vkFreeMemory
> -@ stub vkGetBufferMemoryRequirements
> -@ stub vkGetDeviceMemoryCommitment
> -@ stub vkGetDeviceProcAddr
> -@ stub vkGetDeviceQueue
> -@ stub vkGetDisplayModePropertiesKHR
> -@ stub vkGetDisplayPlaneCapabilitiesKHR
> -@ stub vkGetDisplayPlaneSupportedDisplaysKHR
> -@ stub vkGetEventStatus
> -@ stub vkGetFenceStatus
> -@ stub vkGetImageMemoryRequirements
> -@ stub vkGetImageSparseMemoryRequirements
> -@ stub vkGetImageSubresourceLayout
> +@ stdcall vkEnumeratePhysicalDevices(ptr ptr ptr)
> +@ stdcall vkFlushMappedMemoryRanges(ptr long ptr)
> +@ stdcall vkFreeCommandBuffers(ptr int64 long ptr)
> +@ stdcall vkFreeDescriptorSets(ptr int64 long ptr)
> +@ stdcall vkFreeMemory(ptr int64 ptr)
> +@ stdcall vkGetBufferMemoryRequirements(ptr int64 ptr)
> +@ stdcall vkGetDeviceMemoryCommitment(ptr int64 ptr)
> +@ stdcall vkGetDeviceProcAddr(ptr str)
> +@ stdcall vkGetDeviceQueue(ptr long long ptr)
> +@ stdcall vkGetDisplayModePropertiesKHR(ptr int64 ptr ptr)
> +@ stdcall vkGetDisplayPlaneCapabilitiesKHR(ptr int64 long ptr)
> +@ stdcall vkGetDisplayPlaneSupportedDisplaysKHR(ptr long ptr ptr)
> +@ stdcall vkGetEventStatus(ptr int64)
> +@ stdcall vkGetFenceStatus(ptr int64)
> +@ stdcall vkGetImageMemoryRequirements(ptr int64 ptr)
> +@ stdcall vkGetImageSparseMemoryRequirements(ptr int64 ptr ptr)
> +@ stdcall vkGetImageSubresourceLayout(ptr int64 ptr ptr)
>  @ stdcall vkGetInstanceProcAddr(ptr str)
> -@ stub vkGetPhysicalDeviceDisplayPlanePropertiesKHR
> -@ stub vkGetPhysicalDeviceDisplayPropertiesKHR
> -@ stub vkGetPhysicalDeviceFeatures
> -@ stub vkGetPhysicalDeviceFormatProperties
> -@ stub vkGetPhysicalDeviceImageFormatProperties
> -@ stub vkGetPhysicalDeviceMemoryProperties
> -@ stub vkGetPhysicalDeviceProperties
> -@ stub vkGetPhysicalDeviceQueueFamilyProperties
> -@ stub vkGetPhysicalDeviceSparseImageFormatProperties
> -@ stub vkGetPhysicalDeviceSurfaceCapabilitiesKHR
> -@ stub vkGetPhysicalDeviceSurfaceFormatsKHR
> -@ stub vkGetPhysicalDeviceSurfacePresentModesKHR
> -@ stub vkGetPhysicalDeviceSurfaceSupportKHR
> -@ stub vkGetPhysicalDeviceWin32PresentationSupportKHR
> -@ stub vkGetPipelineCacheData
> -@ stub vkGetQueryPoolResults
> -@ stub vkGetRenderAreaGranularity
> -@ stub vkGetSwapchainImagesKHR
> -@ stub vkInvalidateMappedMemoryRanges
> -@ stub vkMapMemory
> -@ stub vkMergePipelineCaches
> -@ stub vkQueueBindSparse
> -@ stub vkQueuePresentKHR
> -@ stub vkQueueSubmit
> -@ stub vkQueueWaitIdle
> -@ stub vkResetCommandBuffer
> -@ stub vkResetCommandPool
> -@ stub vkResetDescriptorPool
> -@ stub vkResetEvent
> -@ stub vkResetFences
> -@ stub vkSetEvent
> -@ stub vkUnmapMemory
> -@ stub vkUpdateDescriptorSets
> -@ stub vkWaitForFences
> +@ stdcall vkGetPhysicalDeviceDisplayPlanePropertiesKHR(ptr ptr ptr)
> +@ stdcall vkGetPhysicalDeviceDisplayPropertiesKHR(ptr ptr ptr)
> +@ stdcall vkGetPhysicalDeviceFeatures(ptr ptr)
> +@ stdcall vkGetPhysicalDeviceFormatProperties(ptr long ptr)
> +@ stdcall vkGetPhysicalDeviceImageFormatProperties(ptr long long long long long ptr)
> +@ stdcall vkGetPhysicalDeviceMemoryProperties(ptr ptr)
> +@ stdcall vkGetPhysicalDeviceProperties(ptr ptr)
> +@ stdcall vkGetPhysicalDeviceQueueFamilyProperties(ptr ptr ptr)
> +@ stdcall vkGetPhysicalDeviceSparseImageFormatProperties(ptr long long long long long ptr ptr)
> +@ stdcall vkGetPhysicalDeviceSurfaceCapabilitiesKHR(ptr int64 ptr)
> +@ stdcall vkGetPhysicalDeviceSurfaceFormatsKHR(ptr int64 ptr ptr)
> +@ stdcall vkGetPhysicalDeviceSurfacePresentModesKHR(ptr int64 ptr long)
> +@ stdcall vkGetPhysicalDeviceSurfaceSupportKHR(ptr long int64 ptr)
> +@ stdcall vkGetPhysicalDeviceWin32PresentationSupportKHR(ptr long)
> +@ stdcall vkGetPipelineCacheData(ptr int64 ptr ptr)
> +@ stdcall vkGetQueryPoolResults(ptr int64 long long long ptr int64 long)
> +@ stdcall vkGetRenderAreaGranularity(ptr int64 ptr)
> +@ stdcall vkGetSwapchainImagesKHR(ptr int64 ptr ptr)
> +@ stdcall vkInvalidateMappedMemoryRanges(ptr long ptr)
> +@ stdcall vkMapMemory(ptr int64 int64 int64 long ptr)
> +@ stdcall vkMergePipelineCaches(ptr int64 long ptr)
> +@ stdcall vkQueueBindSparse(ptr long ptr int64)
> +@ stdcall vkQueuePresentKHR(ptr ptr)
> +@ stdcall vkQueueSubmit(ptr long ptr int64)
> +@ stdcall vkQueueWaitIdle(ptr)
> +@ stdcall vkResetCommandBuffer(ptr long)
> +@ stdcall vkResetCommandPool(ptr int64 long)
> +@ stdcall vkResetDescriptorPool(ptr int64 long)
> +@ stdcall vkResetEvent(ptr int64)
> +@ stdcall vkResetFences(ptr long ptr)
> +@ stdcall vkSetEvent(ptr int64)
> +@ stdcall vkUnmapMemory(ptr int64)
> +@ stdcall vkUpdateDescriptorSets(ptr long ptr long ptr)
> +@ stdcall vkWaitForFences(ptr long ptr long int64)
> diff --git a/dlls/vulkan-1/vulkan.c b/dlls/vulkan-1/vulkan.c
> index e3981b63ef..879504f6ee 100644
> --- a/dlls/vulkan-1/vulkan.c
> +++ b/dlls/vulkan-1/vulkan.c
> @@ -24,12 +24,16 @@
>
>  #include "wine/debug.h"
>  #include "wine/vulkan.h"
> +#include "vulkan_thunks.h"
>
>  WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
>
> +static VkResult (WINAPI *p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
>  static VkResult (WINAPI *p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *);
>  static void * (WINAPI *p_vk_icdGetInstanceProcAddr)(VkInstance, const char *);
>
> +struct vulkan_funcs vk_funcs;

It's slightly confusing to use "vulkan_funcs" name. struct
vulkan_funcs is defined in vulkan_driver.h. We could rename it to
"loader_vulkan_funcs", or rename the driver struct to
driver_vulkan_funcs to improve clarity.

> +
>  static BOOL vk_loader_init(void)
>  {
>      HMODULE icd_handle = NULL;
> @@ -45,6 +49,10 @@ static BOOL vk_loader_init(void)
>      if (!p_vk_icdGetInstanceProcAddr)
>          return FALSE;
>
> +    p_vkCreateInstance = p_vk_icdGetInstanceProcAddr(NULL, "vkCreateInstance");
> +    if (!p_vkCreateInstance)
> +        return FALSE;
> +
>      p_vkEnumerateInstanceExtensionProperties = p_vk_icdGetInstanceProcAddr(NULL,
>              "vkEnumerateInstanceExtensionProperties");
>      if (!p_vkEnumerateInstanceExtensionProperties)
> @@ -56,8 +64,26 @@ static BOOL vk_loader_init(void)
>  VkResult WINAPI vkCreateInstance(const VkInstanceCreateInfo *create_info,
>          const VkAllocationCallbacks *allocator, VkInstance *instance)
>  {
> -    FIXME("stub: create_info %p, allocator %p, instance %p\n", create_info, allocator, instance);
> -    return VK_ERROR_OUT_OF_HOST_MEMORY;
> +    VkResult res;
> +    TRACE("create_info %p, allocator %p, instance %p\n", create_info, allocator, instance);
> +
> +    res = p_vkCreateInstance(create_info, allocator, instance);
> +    if (res != VK_SUCCESS)
> +        return res;
> +
> +    /* Winevulkan function pointers are generic and can thus be shared.
> +     * There is no need to store a dispatch table at start of 'instance' like
> +     * the official Vulkan loader does.
> +     */
> +    if (!vk_funcs.p_vkGetInstanceProcAddr)
> +    {
> +        TRACE("Loading Vulkan Core functions\n");
> +#define USE_VK_FUNC(name) vk_funcs.p_##name = (void *)p_vk_icdGetInstanceProcAddr(*instance, #name);
> +        ALL_VK_CORE_FUNCS()
> +#undef USE_VK_FUNC
> +    }

There is a race condition. Multiple threads can call
vkCreateInstance(), and one thread can call vulkan-1.dll thunk before
vk_funcs are fully initialized.

> +
> +    return res;
>  }
>
>  VkResult WINAPI vkEnumerateInstanceExtensionProperties(const char *layer_name,
> diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> index b7b37f42cc..5b11d875c0 100755
> --- a/dlls/winevulkan/make_vulkan
> +++ b/dlls/winevulkan/make_vulkan
> @@ -65,6 +65,8 @@ LOGGER.addHandler(logging.StreamHandler())
>  # Filenames to create.
>  WINE_VULKAN_H = "../../include/wine/vulkan.h"
>  WINE_VULKAN_DRIVER_H = "../../include/wine/vulkan_driver.h"
> +WINE_VULKAN_LOADER_C = "../vulkan-1/vulkan_thunks.c"
> +WINE_VULKAN_LOADER_H = "../vulkan-1/vulkan_thunks.h"
>  WINE_VULKAN_LOADER_SPEC = "../vulkan-1/vulkan-1.spec"
>  WINE_VULKAN_THUNKS_C = "vulkan_thunks.c"
>  WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
> @@ -600,6 +602,21 @@ class VkFunction(object):
>          stub += "}\n\n"
>          return stub
>
> +    def loader_thunk(self, call_conv=None, prefix=None):
> +        thunk = self.prototype(call_conv=call_conv, prefix=prefix)
> +        thunk += "\n{\n"
> +        thunk += "    {0}".format(self.trace())
> +
> +        params = ", ".join([p.name for p in self.params])
> +
> +        if self.type != "void":
> +            thunk += "    return vk_funcs.p_{0}({1});\n".format(self.name, params)
> +        else:
> +            thunk += "    vk_funcs.p_{0}({1});\n".format(self.name, params)
> +
> +        thunk += "}\n\n"
> +        return thunk
> +
>      def thunk(self, call_conv=None, prefix=None):
>          thunk = self.prototype(call_conv=call_conv, prefix=prefix)
>          thunk += "\n{\n"
> @@ -2113,6 +2130,57 @@ class VkGenerator(object):
>          f.write("extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);\n\n")
>          f.write("#endif /* __WINE_VULKAN_DRIVER_H */\n")
>
> +    def generate_vulkan_loader_c(self, f):
> +        f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n")
> +
> +        f.write("#include \"config.h\"\n")
> +        f.write("#include \"wine/port.h\"\n\n")
> +
> +        f.write("#include \"wine/debug.h\"\n")
> +        f.write("#include \"wine/vulkan.h\"\n")
> +        f.write("#include \"vulkan_thunks.h\"\n\n")
> +
> +        f.write("WINE_DEFAULT_DEBUG_CHANNEL(vulkan);\n\n")
> +
> +        for func in self.registry.funcs.values():
> +            if not func.is_required():
> +                continue
> +
> +            # Global functions need custom implementation.
> +            if func.is_global_func():
> +                continue
> +
> +            if not func.is_core_func():
> +                continue
> +
> +            f.write(func.loader_thunk(call_conv="WINAPI"))
> +
> +    def generate_vulkan_loader_h(self, f):
> +        f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n")
> +
> +        f.write("struct vulkan_funcs\n{\n")
> +        for func in self.registry.funcs.values():
> +            if not func.is_core_func():
> +                continue
> +
> +            f.write("    {0};\n".format(func.pfn(call_conv="WINAPI")))
> +        f.write("};\n\n")
> +
> +        f.write("#define ALL_VK_CORE_FUNCS() \\\n")
> +        first = True
> +        for func in self.registry.funcs.values():
> +            if not func.is_core_func():
> +                continue
> +
> +            if first:
> +                f.write("    USE_VK_FUNC({0})".format(func.name))
> +                first = False
> +            else:
> +                f.write(" \\\n    USE_VK_FUNC({0})".format(func.name))
> +        f.write("\n\n")
> +
> +        f.write("extern struct vulkan_funcs vk_funcs DECLSPEC_HIDDEN;\n")
> +
>      def generate_vulkan_loader_spec(self, f):
>          f.write("# Automatically generated from Vulkan vk.xml; DO NOT EDIT!\n\n")
>
> @@ -2120,10 +2188,7 @@ class VkGenerator(object):
>              if not func.is_core_func():
>                  continue
>
> -            if func.is_global_func():
> -                f.write(func.spec())
> -            else:
> -                f.write("@ stub {0}\n".format(func.name))
> +            f.write(func.spec())
>
>  class VkRegistry(object):
>      def __init__(self, reg_filename):
> @@ -2506,6 +2571,12 @@ def main():
>      with open(WINE_VULKAN_THUNKS_C, "w") as f:
>          generator.generate_thunks_c(f, "wine_")
>
> +    with open(WINE_VULKAN_LOADER_C, "w") as f:
> +        generator.generate_vulkan_loader_c(f)
> +
> +    with open(WINE_VULKAN_LOADER_H, "w") as f:
> +        generator.generate_vulkan_loader_h(f)
> +
>      with open(WINE_VULKAN_LOADER_SPEC, "w") as f:
>          generator.generate_vulkan_loader_spec(f)
>
> --
> 2.14.3
>
>
>



More information about the wine-devel mailing list