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

Roderick Colenbrander thunderbird2k at gmail.com
Tue Mar 27 19:09:50 CDT 2018


On Tue, Mar 27, 2018 at 3:51 PM, Józef Kucia <joseph.kucia at gmail.com> wrote:
> 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?

I have no problems with the spec approach. Completely forgot about
that method. The only thing we would lose out on would be debug traces
for loader thunks, but I don't think we care much about those. Not
sure which method I prefer most...

> 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