[PATCH v6] winevulkan: Create JSON manifest and registry entry used by official Vulkan loader.

Liam Middlebrook lmiddlebrook at nvidia.com
Mon Mar 30 21:23:47 CDT 2020


Signed-off-by: Liam Middlebrook <lmiddlebrook at nvidia.com>


Thanks,

Liam Middlebrook

On 3/30/20 5:35 PM, Brendan Shanks wrote:
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47109
> Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
> ---
> v6: As recommended by Alexandre, the JSON file is now generated by
> make_vulkan and stored in resources.
> The library_path in the JSON file is now a relative path, this is
> simpler and is what NVIDIA and AMD ICDs do on Windows.
> 
>   dlls/winevulkan/Makefile.in     |  5 +-
>   dlls/winevulkan/make_vulkan     | 16 +++++++
>   dlls/winevulkan/vulkan.c        | 85 +++++++++++++++++++++++++++++++++
>   dlls/winevulkan/winevulkan.json |  7 +++
>   dlls/winevulkan/winevulkan.rc   | 21 ++++++++
>   dlls/winevulkan/winevulkan.spec |  2 +
>   loader/wine.inf.in              |  1 +
>   7 files changed, 135 insertions(+), 2 deletions(-)
>   create mode 100644 dlls/winevulkan/winevulkan.json
>   create mode 100644 dlls/winevulkan/winevulkan.rc
> 
> diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in
> index e0bca6fad7..d832a2a8f8 100644
> --- a/dlls/winevulkan/Makefile.in
> +++ b/dlls/winevulkan/Makefile.in
> @@ -1,9 +1,10 @@
>   MODULE    = winevulkan.dll
>   IMPORTLIB = winevulkan
> -IMPORTS   = user32 gdi32
> +IMPORTS   = user32 gdi32 advapi32
>   
>   C_SRCS = \
>   	vulkan.c \
>   	vulkan_thunks.c
>   
> -RC_SRCS = version.rc
> +RC_SRCS = version.rc \
> +          winevulkan.rc
> diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> index e5b3a1fdfa..1811d5ae10 100755
> --- a/dlls/winevulkan/make_vulkan
> +++ b/dlls/winevulkan/make_vulkan
> @@ -71,6 +71,7 @@ WINE_VK_VERSION = (1, 2)
>   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_JSON = "winevulkan.json"
>   WINE_VULKAN_SPEC = "winevulkan.spec"
>   WINE_VULKAN_THUNKS_C = "vulkan_thunks.c"
>   WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
> @@ -2526,6 +2527,9 @@ class VkGenerator(object):
>               else:
>                   f.write("@ stub {0}\n".format(func.name))
>   
> +        f.write("@ stdcall -private DllRegisterServer()\n")
> +        f.write("@ stdcall -private DllUnregisterServer()\n")
> +
>       def generate_vulkan_loader_spec(self, f):
>           self._generate_copyright(f, spec_file=True)
>   
> @@ -3033,6 +3037,15 @@ class VkRegistry(object):
>           self.handles = sorted(handles, key=lambda handle: handle.name)
>           self.structs = sorted(structs, key=lambda struct: struct.name)
>   
> +def generate_vulkan_json(f):
> +    f.write("{\n")
> +    f.write("    \"file_format_version\": \"1.0.0\",\n")
> +    f.write("    \"ICD\": {\n")
> +    f.write("        \"library_path\": \".\\\\winevulkan.dll\",\n")
> +    f.write("        \"api_version\": \"{0}\"\n".format(VK_XML_VERSION))
> +    f.write("    }\n")
> +    f.write("}\n")
> +
>   def set_working_directory():
>       path = os.path.abspath(__file__)
>       path = os.path.dirname(path)
> @@ -3074,6 +3087,9 @@ def main():
>       with open(WINE_VULKAN_THUNKS_C, "w") as f:
>           generator.generate_thunks_c(f, "wine_")
>   
> +    with open(WINE_VULKAN_JSON, "w") as f:
> +        generate_vulkan_json(f)
> +
>       with open(WINE_VULKAN_SPEC, "w") as f:
>           generator.generate_vulkan_spec(f)
>   
> diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
> index 59472bcef8..3a894d4e1f 100644
> --- a/dlls/winevulkan/vulkan.c
> +++ b/dlls/winevulkan/vulkan.c
> @@ -21,6 +21,7 @@
>   
>   #include "windef.h"
>   #include "winbase.h"
> +#include "winreg.h"
>   #include "winuser.h"
>   
>   #include "vulkan_private.h"
> @@ -50,6 +51,7 @@ static void *wine_vk_find_struct_(void *s, VkStructureType t)
>   
>   static void *wine_vk_get_global_proc_addr(const char *name);
>   
> +static HINSTANCE hinstance;
>   static const struct vulkan_funcs *vk_funcs;
>   static VkResult (*p_vkEnumerateInstanceVersion)(uint32_t *version);
>   
> @@ -1268,6 +1270,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
>       switch (reason)
>       {
>           case DLL_PROCESS_ATTACH:
> +            hinstance = hinst;
>               DisableThreadLibraryCalls(hinst);
>               return wine_vk_init();
>       }
> @@ -1307,3 +1310,85 @@ void *native_vkGetInstanceProcAddrWINE(VkInstance instance, const char *name)
>   {
>       return vk_funcs->p_vkGetInstanceProcAddr(instance, name);
>   }
> +
> +
> +static const WCHAR winevulkan_json_resW[] = {'w','i','n','e','v','u','l','k','a','n','_','j','s','o','n',0};
> +static const WCHAR winevulkan_json_pathW[] = {'\\','w','i','n','e','v','u','l','k','a','n','.','j','s','o','n',0};
> +static const WCHAR vulkan_driversW[] = {'S','o','f','t','w','a','r','e','\\','K','h','r','o','n','o','s','\\',
> +                                        'V','u','l','k','a','n','\\','D','r','i','v','e','r','s',0};
> +
> +HRESULT WINAPI DllRegisterServer(void)
> +{
> +    WCHAR json_path[MAX_PATH];
> +    HRSRC rsrc;
> +    const char *data;
> +    DWORD datalen, written, zero = 0;
> +    HANDLE file;
> +    HKEY key;
> +
> +    /* Create the JSON manifest and registry key to register this ICD with the official Vulkan loader. */
> +    TRACE("\n");
> +    rsrc = FindResourceW(hinstance, winevulkan_json_resW, (const WCHAR *)RT_RCDATA);
> +    if (!rsrc)
> +    {
> +        ERR("Unable to find resource.\n");
> +        return E_UNEXPECTED;
> +    }
> +    data = LockResource(LoadResource(hinstance, rsrc));
> +    datalen = SizeofResource(hinstance, rsrc);
> +
> +    GetSystemDirectoryW(json_path, ARRAY_SIZE(json_path));
> +    lstrcatW(json_path, winevulkan_json_pathW);
> +    file = CreateFileW(json_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
> +    if (file == INVALID_HANDLE_VALUE)
> +    {
> +        ERR("Unable to create JSON manifest.\n");
> +        return E_UNEXPECTED;
> +    }
> +
> +    if (WriteFile(file, data, datalen, &written, NULL) == FALSE)
> +    {
> +        ERR("Unable to write to JSON manifest.\n");
> +        CloseHandle(file);
> +        return E_UNEXPECTED;
> +    }
> +
> +    CloseHandle(file);
> +
> +    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, vulkan_driversW, 0, NULL, 0, KEY_SET_VALUE,
> +                        NULL, &key, NULL) != ERROR_SUCCESS)
> +    {
> +        ERR("Unable to create registry key.\n");
> +        return E_UNEXPECTED;
> +    }
> +
> +    if (RegSetValueExW(key, json_path, 0, REG_DWORD, (const BYTE *)&zero, sizeof(zero)) != ERROR_SUCCESS)
> +    {
> +        ERR("Unable to set registry value.\n");
> +        RegCloseKey(key);
> +        return E_UNEXPECTED;
> +    }
> +
> +    RegCloseKey(key);
> +    return S_OK;
> +}
> +
> +HRESULT WINAPI DllUnregisterServer(void)
> +{
> +    WCHAR json_path[MAX_PATH];
> +    HKEY key;
> +
> +    /* Remove the JSON manifest and registry key */
> +    TRACE("\n");
> +    GetSystemDirectoryW(json_path, ARRAY_SIZE(json_path));
> +    lstrcatW(json_path, winevulkan_json_pathW);
> +    DeleteFileW(json_path);
> +
> +    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, vulkan_driversW, 0, KEY_SET_VALUE, &key) == ERROR_SUCCESS)
> +    {
> +        RegDeleteValueW(key, json_path);
> +        RegCloseKey(key);
> +    }
> +
> +    return S_OK;
> +}
> diff --git a/dlls/winevulkan/winevulkan.json b/dlls/winevulkan/winevulkan.json
> new file mode 100644
> index 0000000000..993bf8f949
> --- /dev/null
> +++ b/dlls/winevulkan/winevulkan.json
> @@ -0,0 +1,7 @@
> +{
> +    "file_format_version": "1.0.0",
> +    "ICD": {
> +        "library_path": ".\\winevulkan.dll",
> +        "api_version": "1.2.134"
> +    }
> +}
> diff --git a/dlls/winevulkan/winevulkan.rc b/dlls/winevulkan/winevulkan.rc
> new file mode 100644
> index 0000000000..740c7f7878
> --- /dev/null
> +++ b/dlls/winevulkan/winevulkan.rc
> @@ -0,0 +1,21 @@
> +/* Wine Vulkan resources
> + *
> + * Copyright 2020 Brendan Shanks 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
> + */
> +
> +/* @makedep: winevulkan.json */
> +winevulkan_json RCDATA winevulkan.json
> diff --git a/dlls/winevulkan/winevulkan.spec b/dlls/winevulkan/winevulkan.spec
> index c02af5aeaa..e024a43586 100644
> --- a/dlls/winevulkan/winevulkan.spec
> +++ b/dlls/winevulkan/winevulkan.spec
> @@ -239,3 +239,5 @@
>   @ stdcall -private wine_vkUpdateDescriptorSets(ptr long ptr long ptr)
>   @ stdcall -private wine_vkWaitForFences(ptr long ptr long int64)
>   @ stdcall -private wine_vkWaitSemaphores(ptr ptr int64)
> +@ stdcall -private DllRegisterServer()
> +@ stdcall -private DllUnregisterServer()
> diff --git a/loader/wine.inf.in b/loader/wine.inf.in
> index ad79c084dd..271a422506 100644
> --- a/loader/wine.inf.in
> +++ b/loader/wine.inf.in
> @@ -2570,6 +2570,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
>   11,,windowscodecs.dll,1
>   11,,winegstreamer.dll,1
>   11,,wineqtdecoder.dll,1
> +11,,winevulkan.dll,1
>   11,,wintrust.dll,1
>   11,,iexplore.exe,1
>   
> 

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------



More information about the wine-devel mailing list