[PATCH 2/5] vulkan-1: Add stub implementation.

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


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>
> ---
>  configure.ac                |   1 +
>  dlls/vulkan-1/Makefile.in   |   6 ++
>  dlls/vulkan-1/version.rc    |  27 ++++++++
>  dlls/vulkan-1/vulkan-1.spec | 158 ++++++++++++++++++++++++++++++++++++++++++++
>  dlls/vulkan-1/vulkan.c      |  70 ++++++++++++++++++++
>  dlls/winevulkan/make_vulkan |  81 ++++++++++++++++++++---
>  6 files changed, 335 insertions(+), 8 deletions(-)
>  create mode 100644 dlls/vulkan-1/Makefile.in
>  create mode 100644 dlls/vulkan-1/version.rc
>  create mode 100644 dlls/vulkan-1/vulkan-1.spec
>  create mode 100644 dlls/vulkan-1/vulkan.c
>
> diff --git a/configure.ac b/configure.ac
> index 6a30601ca0..60c410c1f1 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -3692,6 +3692,7 @@ WINE_CONFIG_MAKEFILE(dlls/vnbt.vxd,enable_win16)
>  WINE_CONFIG_MAKEFILE(dlls/vnetbios.vxd,enable_win16)
>  WINE_CONFIG_MAKEFILE(dlls/vssapi)
>  WINE_CONFIG_MAKEFILE(dlls/vtdapi.vxd,enable_win16)
> +WINE_CONFIG_MAKEFILE(dlls/vulkan-1)
>  WINE_CONFIG_MAKEFILE(dlls/vwin32.vxd,enable_win16)
>  WINE_CONFIG_MAKEFILE(dlls/w32skrnl,enable_win16)
>  WINE_CONFIG_MAKEFILE(dlls/w32sys.dll16,enable_win16)
> diff --git a/dlls/vulkan-1/Makefile.in b/dlls/vulkan-1/Makefile.in
> new file mode 100644
> index 0000000000..e137fd277f
> --- /dev/null
> +++ b/dlls/vulkan-1/Makefile.in
> @@ -0,0 +1,6 @@
> +MODULE    = vulkan-1.dll
> +
> +C_SRCS = \
> +       vulkan.c
> +
> +RC_SRCS = version.rc
> diff --git a/dlls/vulkan-1/version.rc b/dlls/vulkan-1/version.rc
> new file mode 100644
> index 0000000000..ec75462ddf
> --- /dev/null
> +++ b/dlls/vulkan-1/version.rc
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright 2018 Roderick Colenbrander
> + *
> + * 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
> + */
> +
> +#include "config.h" /* Needed to get PACKAGE_VERSION */
> +
> +#define WINE_FILEDESCRIPTION_STR "Wine Vulkan Loader"
> +#define WINE_FILENAME_STR "vulkan-1.dll"
> +#define WINE_FILEVERSION_STR PACKAGE_VERSION
> +#define WINE_PRODUCTVERSION_STR PACKAGE_VERSION
> +#define WINE_PRODUCTNAME_STR "Wine Vulkan"
> +
> +#include "wine/wine_common_ver.rc"
> diff --git a/dlls/vulkan-1/vulkan-1.spec b/dlls/vulkan-1/vulkan-1.spec
> new file mode 100644
> index 0000000000..088a3f23ac
> --- /dev/null
> +++ b/dlls/vulkan-1/vulkan-1.spec
> @@ -0,0 +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 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 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 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
> diff --git a/dlls/vulkan-1/vulkan.c b/dlls/vulkan-1/vulkan.c
> new file mode 100644
> index 0000000000..b8db08a312
> --- /dev/null
> +++ b/dlls/vulkan-1/vulkan.c
> @@ -0,0 +1,70 @@
> +/* Wine Vulkan loader implementation
> + *
> + * Copyright 2018 Roderick Colenbrander
> + *
> + * 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
> + */
> +
> +#include <stdarg.h>
> +
> +#include "windef.h"
> +#include "winbase.h"
> +
> +#include "wine/debug.h"
> +#include "wine/vulkan.h"
> +
> +WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
> +
> +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 WINAPI vkEnumerateInstanceExtensionProperties(const char *layer_name,
> +        uint32_t *count, VkExtensionProperties *properties)
> +{
> +    FIXME("stub: %p %p %p\n", layer_name, count, properties);
> +    return VK_ERROR_OUT_OF_HOST_MEMORY;
> +}
> +
> +VkResult WINAPI vkEnumerateInstanceLayerProperties(uint32_t *count, VkLayerProperties *properties)
> +{
> +    TRACE("%p, %p\n", count, properties);
> +
> +    /* We don't support any layers. */
> +    *count = 0;
> +    return VK_SUCCESS;
> +}
> +
> +PFN_vkVoidFunction WINAPI vkGetInstanceProcAddr(VkInstance instance, const char *name)
> +{
> +    FIXME("stub: %p %s\n", instance, debugstr_a(name));
> +    return NULL;
> +}
> +
> +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
> +{
> +    TRACE("(%p, %u, %p)\n", hinst, reason, reserved);
> +
> +    switch (reason)
> +    {
> +        case DLL_PROCESS_ATTACH:
> +            DisableThreadLibraryCalls(hinst);
> +            return TRUE;
> +    }
> +    return TRUE;
> +}

I think we should prefer native Vulkan loader.

> diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> index bb02b2aa92..b7b37f42cc 100755
> --- a/dlls/winevulkan/make_vulkan
> +++ b/dlls/winevulkan/make_vulkan
> @@ -65,6 +65,7 @@ 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_SPEC = "../vulkan-1/vulkan-1.spec"
>  WINE_VULKAN_THUNKS_C = "vulkan_thunks.c"
>  WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
>
> @@ -107,6 +108,15 @@ BLACKLISTED_EXTENSIONS = [
>      "VK_NV_external_memory_win32"
>  ]
>
> +# The Vulkan provides entry-points for core functionality and some important
> +# extension. Based on vulkan-1.def this amounts to WSI extensions on 1.0.51.
> +CORE_EXTENSIONS = [
> +    "VK_KHR_display",
> +    "VK_KHR_surface",
> +    "VK_KHR_swapchain",
> +    "VK_KHR_win32_surface"
> +]

Please add VK_KHR_display_swapchain to "CORE_EXTENSIONS".

> +
>  # Functions part of our winevulkan graphics driver interface.
>  # DRIVER_VERSION should be bumped on any change to driver interface
>  # in FUNCTION_OVERRIDES
> @@ -382,6 +392,21 @@ class VkFunction(object):
>
>          return conversions
>
> +    def is_core_func(self):
> +        """ Returns if the function is a Vulkan core function.
> +        We consider core functions to be functions any global, instance or
> +        device functions not belonging to an extension in addition to a few
> +        KHR WSI extensions exported by the loader.
> +        """

Please fix the comment above.

> +
> +        if self.extension is None:
> +            return True
> +
> +        if self.extension in CORE_EXTENSIONS:
> +            return True
> +
> +        return False
> +
>      def is_device_func(self):
>          # If none of the other, it must be a device function
>          return not self.is_global_func() and not self.is_instance_func()
> @@ -555,6 +580,11 @@ class VkFunction(object):
>
>          return body
>
> +    def spec(self):
> +        """ Generate spec file entry for this function. """
> +        params = " ".join([p.spec() for p in self.params])
> +        return "@ stdcall {0}({1})\n".format(self.name, params)
> +
>      def stub(self, call_conv=None, prefix=None):
>          stub = self.prototype(call_conv=call_conv, prefix=prefix)
>          stub += "\n{\n"
> @@ -1300,6 +1330,28 @@ class VkParam(object):
>      def needs_output_conversion(self):
>          return self.output_conv is not None
>
> +    def spec(self):
> +        """ Generate spec file entry for this parameter. """
> +
> +        if self.type_info["category"] == "bitmask":
> +            return "long"
> +        if self.type_info["category"] == "enum":
> +            return "long"

It could be rewritten as:

if self.type_info["category"] in ["bitmask", "enum"]:
    return "long"

> +        if self.is_pointer() and self.type == "char":
> +            return "str"
> +        if self.is_dispatchable() or self.is_pointer() or self.is_static_array():
> +            return "ptr"
> +        if self.is_handle() and not self.is_dispatchable():
> +            return "int64"
> +        if self.type == "float":
> +            return "float"
> +        if self.type in ["int", "int32_t", "size_t", "uint32_t", "VkBool32"]:
> +            return "long"
> +        if self.type in ["uint64_t", "VkDeviceSize"]:
> +            return "int64"
> +
> +        LOGGER.error("Unhandled spec conversion for type: {0}".format(self.type))
> +
>      def variable(self, conv=False):
>          """ Returns 'glue' code during generation of a function call on how to access the variable.
>          This function handles various scenarios such as 'unwrapping' if dispatchable objects and
> @@ -2061,6 +2113,17 @@ 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_spec(self, f):
> +        f.write("# Automatically generated from Vulkan vk.xml; DO NOT EDIT!\n\n")
> +
> +        for func in self.registry.funcs.values():
> +            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))
>
>  class VkRegistry(object):
>      def __init__(self, reg_filename):
> @@ -2201,6 +2264,13 @@ class VkRegistry(object):
>          for ext in exts:
>              ext_name = ext.attrib["name"]
>
> +            # Set extension name on any functions calls part of this extension as we
> +            # were not aware of the name during initial parsing.
> +            commands = ext.findall("require/command")
> +            for command in commands:
> +                cmd_name = command.attrib["name"]
> +                self.funcs[cmd_name].extension = ext_name
> +
>              # Some extensions are not ready or have numbers reserved as a place holder.
>              if ext.attrib["supported"] == "disabled":
>                  LOGGER.debug("Skipping disabled extension: {0}".format(ext_name))
> @@ -2267,20 +2337,12 @@ class VkRegistry(object):
>              ext_info = {"name" : ext_name, "type" : ext_type}
>              extensions.append(ext_info)
>
> -            commands = ext.findall("require/command")
> -            if not commands:
> -                continue
> -
>              # Pull in any commands we need. We infer types to pull in from the command
>              # as well.
>              for command in commands:
>                  cmd_name = command.attrib["name"]
>                  self._mark_command_required(cmd_name)
>
> -                # Set extension name on the function call as we were not aware of the
> -                # name during initial parsing.
> -                self.funcs[cmd_name].extension = ext_name
> -
>          # Sort in alphabetical order.
>          self.extensions = sorted(extensions, key=lambda ext: ext["name"])
>
> @@ -2444,5 +2506,8 @@ def main():
>      with open(WINE_VULKAN_THUNKS_C, "w") as f:
>          generator.generate_thunks_c(f, "wine_")
>
> +    with open(WINE_VULKAN_LOADER_SPEC, "w") as f:
> +        generator.generate_vulkan_loader_spec(f)
> +
>  if __name__ == "__main__":
>      main()
> --
> 2.14.3
>
>
>



More information about the wine-devel mailing list