demos: Make the demos work in the Windows build.

Commit 02fe9f5bdf introduced linking the
Windows build of the demos with d3d12 and dxgi, while also still linking
to libvkd3d-utils.la. That happens to more or less work on Wine; we get
vkd3d-utils' D3D12CreateDevice(), and Wine's
IDXGIFactory2_CreateSwapChainForHwnd(), but because Wine's
implementation of d3d12 swapchains uses vkd3d, we're able to use the
resulting swapchain buffers even though the instance of vkd3d used by
Wine may not be the same instance of vkd3d used by the demos. Perhaps
unsurprisingly, things don't go nearly as well on Windows.

We could of course stop linking the demos to vkd3d-utils on Windows, but
that's not that interesting; we're trying to show what vkd3d can do
here, not what d3d12 can do.
This commit is contained in:
Henri Verbeet
2025-04-21 18:02:41 +02:00
parent 883ffc5fd6
commit dfe3ad5551
Notes: Henri Verbeet 2025-04-28 13:01:05 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1468
6 changed files with 142 additions and 31 deletions

View File

@@ -184,7 +184,7 @@ AC_CHECK_FUNCS([pthread_threadid_np])
dnl Makefiles
case $host_os in
mingw32*)
AC_SUBST([DEMO_LIBS],["-ld3d12 -ldxgi -lgdi32"])
AC_SUBST([DEMO_LIBS],["-lgdi32"])
AC_SUBST([DEMO_CFLAGS],["-municode"])
;;
*) AS_IF([test "x$enable_demos" = "xyes" -a "x$HAVE_XCB" != "xyes"],

View File

@@ -174,9 +174,11 @@ static inline HRESULT demo_create_root_signature(ID3D12Device *device,
return hr;
}
#ifdef _WIN32
#ifdef VKD3D_CROSSTEST
#include "demo_d3d12.h"
#else
#define INFINITE VKD3D_INFINITE
# ifndef _WIN32
# define INFINITE VKD3D_INFINITE
# endif
#include "demo_vkd3d.h"
#endif

View File

@@ -29,7 +29,10 @@ struct demo_win32
struct demo
{
struct demo_win32 win32;
union
{
struct demo_win32 win32;
} u;
size_t window_count;
@@ -76,7 +79,7 @@ static inline void demo_cleanup(struct demo *demo)
static inline bool demo_init(struct demo *demo, void *user_data)
{
if (!demo_win32_init(&demo->win32))
if (!demo_win32_init(&demo->u.win32))
{
fprintf(stderr, "Failed to initialise demo.\n");
return false;

View File

@@ -17,16 +17,25 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VK_NO_PROTOTYPES
#define VK_USE_PLATFORM_XCB_KHR
#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_15
#include "config.h"
#define VK_NO_PROTOTYPES
#ifdef _WIN32
# define VK_USE_PLATFORM_WIN32_KHR
#endif
#ifdef HAVE_XCB
# define VK_USE_PLATFORM_XCB_KHR
#endif
#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_15
#include <vkd3d.h>
#include <vkd3d_utils.h>
#include <xcb/xcb_event.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h>
#include <dlfcn.h>
#ifdef HAVE_XCB
# include <xcb/xcb_event.h>
# include <xcb/xcb_icccm.h>
# include <xcb/xcb_keysyms.h>
#endif
#ifndef _WIN32
# include <dlfcn.h>
#endif
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
@@ -35,7 +44,12 @@
DECLARE_VK_PFN(vkAcquireNextImageKHR)
DECLARE_VK_PFN(vkCreateFence)
DECLARE_VK_PFN(vkCreateSwapchainKHR)
#ifdef _WIN32
DECLARE_VK_PFN(vkCreateWin32SurfaceKHR)
#endif
#ifdef HAVE_XCB
DECLARE_VK_PFN(vkCreateXcbSurfaceKHR)
#endif
DECLARE_VK_PFN(vkDestroyFence)
DECLARE_VK_PFN(vkDestroySurfaceKHR)
DECLARE_VK_PFN(vkDestroySwapchainKHR)
@@ -47,18 +61,31 @@ DECLARE_VK_PFN(vkQueuePresentKHR)
DECLARE_VK_PFN(vkResetFences)
DECLARE_VK_PFN(vkWaitForFences)
struct demo_win32
{
#ifdef _WIN32
UINT (*GetDpiForSystem)(void);
#endif
};
struct demo_xcb
{
#ifdef HAVE_XCB
xcb_connection_t *connection;
xcb_atom_t wm_protocols_atom;
xcb_atom_t wm_delete_window_atom;
xcb_key_symbols_t *xcb_keysyms;
int screen;
#endif
};
struct demo
{
struct demo_xcb xcb;
union
{
struct demo_win32 win32;
struct demo_xcb xcb;
} u;
struct demo_window **windows;
size_t windows_size;
@@ -66,6 +93,11 @@ struct demo
void *user_data;
void (*idle_func)(struct demo *demo, void *user_data);
struct demo_window *(*create_window)(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void *user_data);
void (*get_dpi)(struct demo *demo, double *dpi_x, double *dpi_y);
void (*process_events)(struct demo *demo);
void (*cleanup)(struct demo *demo);
};
struct demo_window
@@ -75,6 +107,8 @@ struct demo_window
void *user_data;
void (*expose_func)(struct demo_window *window, void *user_data);
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data);
VkSurfaceKHR (*create_vk_surface)(struct demo_window *window, VkInstance vk_instance);
void (*destroy)(struct demo_window *window);
};
static inline bool demo_add_window(struct demo *demo, struct demo_window *window)
@@ -111,7 +145,9 @@ static inline void demo_remove_window(struct demo *demo, const struct demo_windo
}
}
static inline bool demo_window_init(struct demo_window *window, struct demo *demo, void *user_data)
static inline bool demo_window_init(struct demo_window *window, struct demo *demo, void *user_data,
VkSurfaceKHR (*create_vk_surface)(struct demo_window *window, VkInstance vk_instance),
void (*destroy)(struct demo_window *window))
{
if (!demo_add_window(demo, window))
return false;
@@ -120,6 +156,8 @@ static inline bool demo_window_init(struct demo_window *window, struct demo *dem
window->user_data = user_data;
window->expose_func = NULL;
window->key_press_func = NULL;
window->create_vk_surface = create_vk_surface;
window->destroy = destroy;
return true;
}
@@ -129,23 +167,45 @@ static inline void demo_window_cleanup(struct demo_window *window)
demo_remove_window(window->demo, window);
}
#include "demo_xcb.h"
#ifdef _WIN32
# include "demo_win32.h"
#endif
#ifdef HAVE_XCB
# include "demo_xcb.h"
#endif
static void load_vulkan_procs(void)
{
void *libvulkan;
#ifdef _WIN32
if (!(libvulkan = LoadLibraryA(SONAME_LIBVULKAN)))
{
fprintf(stderr, "Failed to load %s.\n", SONAME_LIBVULKAN);
exit(1);
}
#else
if (!(libvulkan = dlopen(SONAME_LIBVULKAN, RTLD_NOW)))
{
fprintf(stderr, "Failed to load %s: %s.\n", SONAME_LIBVULKAN, dlerror());
exit(1);
}
#endif
#define LOAD_VK_PFN(name) name = (void *)dlsym(libvulkan, #name);
#ifdef _WIN32
# define LOAD_VK_PFN(name) name = (void *)GetProcAddress(libvulkan, #name);
#else
# define LOAD_VK_PFN(name) name = (void *)dlsym(libvulkan, #name);
#endif
LOAD_VK_PFN(vkAcquireNextImageKHR)
LOAD_VK_PFN(vkCreateFence)
LOAD_VK_PFN(vkCreateSwapchainKHR)
#ifdef _WIN32
LOAD_VK_PFN(vkCreateWin32SurfaceKHR)
#endif
#ifdef HAVE_XCB
LOAD_VK_PFN(vkCreateXcbSurfaceKHR)
#endif
LOAD_VK_PFN(vkDestroyFence)
LOAD_VK_PFN(vkDestroySurfaceKHR)
LOAD_VK_PFN(vkDestroySwapchainKHR)
@@ -179,13 +239,34 @@ struct demo_swapchain
static inline void demo_cleanup(struct demo *demo)
{
free(demo->windows);
demo_xcb_cleanup(demo);
demo->cleanup(demo);
}
static inline bool demo_init(struct demo *demo, void *user_data)
{
if (!demo_xcb_init(&demo->xcb))
#ifdef _WIN32
if (demo_win32_init(&demo->u.win32))
{
demo->create_window = demo_window_win32_create;
demo->get_dpi = demo_win32_get_dpi;
demo->process_events = demo_win32_process_events;
demo->cleanup = demo_win32_cleanup;
}
#endif
#ifdef HAVE_XCB
if (demo_xcb_init(&demo->u.xcb))
{
demo->create_window = demo_window_xcb_create;
demo->get_dpi = demo_xcb_get_dpi;
demo->process_events = demo_xcb_process_events;
demo->cleanup = demo_xcb_cleanup;
}
#endif
else
{
fprintf(stderr, "Failed to initialise demo.\n");
return false;
}
demo->windows = NULL;
demo->windows_size = 0;
@@ -198,12 +279,12 @@ static inline bool demo_init(struct demo *demo, void *user_data)
static inline void demo_get_dpi(struct demo *demo, double *dpi_x, double *dpi_y)
{
demo_xcb_get_dpi(demo, dpi_x, dpi_y);
demo->get_dpi(demo, dpi_x, dpi_y);
}
static inline void demo_process_events(struct demo *demo)
{
demo_xcb_process_events(demo);
demo->process_events(demo);
}
static inline void demo_set_idle_func(struct demo *demo,
@@ -214,13 +295,13 @@ static inline void demo_set_idle_func(struct demo *demo,
static inline void demo_window_destroy(struct demo_window *window)
{
demo_window_xcb_destroy(window);
window->destroy(window);
}
static inline struct demo_window *demo_window_create(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void *user_data)
{
return demo_window_xcb_create(demo, title, width, height, user_data);
return demo->create_window(demo, title, width, height, user_data);
}
static inline void demo_window_set_expose_func(struct demo_window *window,
@@ -269,7 +350,7 @@ static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *c
vk_physical_device = vkd3d_get_vk_physical_device(d3d12_device);
vk_device = vkd3d_get_vk_device(d3d12_device);
if (!(vk_surface = demo_window_xcb_create_vk_surface(window, vk_instance)))
if (!(vk_surface = window->create_vk_surface(window, vk_instance)))
{
ID3D12Device_Release(d3d12_device);
return NULL;

View File

@@ -27,6 +27,25 @@ struct demo_window_win32
HWND window;
};
#ifndef VKD3D_CROSSTEST
static VkSurfaceKHR demo_window_win32_create_vk_surface(struct demo_window *window, VkInstance vk_instance)
{
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w);
struct VkWin32SurfaceCreateInfoKHR surface_desc;
VkSurfaceKHR vk_surface;
surface_desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surface_desc.pNext = NULL;
surface_desc.flags = 0;
surface_desc.hinstance = window_win32->instance;
surface_desc.hwnd = window_win32->window;
if (vkCreateWin32SurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface) < 0)
return VK_NULL_HANDLE;
return vk_surface;
}
#endif
static void demo_window_win32_destroy(struct demo_window *window)
{
struct demo_window_win32 *window_win32 = CONTAINING_RECORD(window, struct demo_window_win32, w);
@@ -54,7 +73,12 @@ static struct demo_window *demo_window_win32_create(struct demo *demo, const cha
if (!(window_win32 = malloc(sizeof(*window_win32))))
return NULL;
#ifdef VKD3D_CROSSTEST
if (!demo_window_init(&window_win32->w, demo, user_data))
#else
if (!demo_window_init(&window_win32->w, demo, user_data,
demo_window_win32_create_vk_surface, demo_window_win32_destroy))
#endif
{
free(window_win32);
return NULL;
@@ -89,7 +113,7 @@ static struct demo_window *demo_window_win32_create(struct demo *demo, const cha
static void demo_win32_get_dpi(struct demo *demo, double *dpi_x, double *dpi_y)
{
struct demo_win32 *win32 = &demo->win32;
struct demo_win32 *win32 = &demo->u.win32;
*dpi_x = *dpi_y = win32->GetDpiForSystem();
}

View File

@@ -78,7 +78,7 @@ static VkSurfaceKHR demo_window_xcb_create_vk_surface(struct demo_window *window
surface_desc.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
surface_desc.pNext = NULL;
surface_desc.flags = 0;
surface_desc.connection = window->demo->xcb.connection;
surface_desc.connection = window->demo->u.xcb.connection;
surface_desc.window = window_xcb->window;
if (vkCreateXcbSurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface) < 0)
return VK_NULL_HANDLE;
@@ -89,7 +89,7 @@ static VkSurfaceKHR demo_window_xcb_create_vk_surface(struct demo_window *window
static void demo_window_xcb_destroy(struct demo_window *window)
{
struct demo_window_xcb *window_xcb = CONTAINING_RECORD(window, struct demo_window_xcb, w);
struct demo_xcb *xcb = &window->demo->xcb;
struct demo_xcb *xcb = &window->demo->u.xcb;
xcb_destroy_window(xcb->connection, window_xcb->window);
xcb_flush(xcb->connection);
@@ -100,8 +100,8 @@ static void demo_window_xcb_destroy(struct demo_window *window)
static struct demo_window *demo_window_xcb_create(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void *user_data)
{
struct demo_xcb *xcb = &demo->u.xcb;
struct demo_window_xcb *window_xcb;
struct demo_xcb *xcb = &demo->xcb;
xcb_size_hints_t hints;
xcb_screen_t *screen;
@@ -113,7 +113,8 @@ static struct demo_window *demo_window_xcb_create(struct demo *demo, const char
if (!(window_xcb = malloc(sizeof(*window_xcb))))
return NULL;
if (!demo_window_init(&window_xcb->w, demo, user_data))
if (!demo_window_init(&window_xcb->w, demo, user_data,
demo_window_xcb_create_vk_surface, demo_window_xcb_destroy))
{
free(window_xcb);
return NULL;
@@ -144,7 +145,7 @@ static struct demo_window *demo_window_xcb_create(struct demo *demo, const char
static void demo_xcb_get_dpi(struct demo *demo, double *dpi_x, double *dpi_y)
{
struct demo_xcb *xcb = &demo->xcb;
struct demo_xcb *xcb = &demo->u.xcb;
xcb_screen_t *screen;
if (!(screen = demo_xcb_get_screen(xcb->connection, xcb->screen)))
@@ -161,8 +162,8 @@ static void demo_xcb_process_events(struct demo *demo)
{
const struct xcb_client_message_event_t *client_message;
struct xcb_key_press_event_t *key_press;
struct demo_xcb *xcb = &demo->u.xcb;
struct demo_window_xcb *window_xcb;
struct demo_xcb *xcb = &demo->xcb;
xcb_generic_event_t *event;
xcb_keysym_t sym;
@@ -212,7 +213,7 @@ static void demo_xcb_process_events(struct demo *demo)
static void demo_xcb_cleanup(struct demo *demo)
{
struct demo_xcb *xcb = &demo->xcb;
struct demo_xcb *xcb = &demo->u.xcb;
xcb_key_symbols_free(xcb->xcb_keysyms);
xcb_disconnect(xcb->connection);