# HG changeset patch # User John Tsiombikas # Date 1506083189 -10800 # Node ID c31c4115d44a3c988cd0690c3016520e1ca7b3a6 # Parent 68e1c437343f4347314293177b672cc6015561cf test 2, open window, create queue, etc ... diff -r 68e1c437343f -r c31c4115d44a .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Sep 22 15:26:29 2017 +0300 @@ -0,0 +1,4 @@ +\.o$ +\.swp$ +\.d$ +^test$ diff -r 68e1c437343f -r c31c4115d44a Makefile --- a/Makefile Fri Sep 22 01:01:10 2017 +0300 +++ b/Makefile Fri Sep 22 15:26:29 2017 +0300 @@ -3,7 +3,7 @@ bin = test CFLAGS = -pedantic -Wall -g -LDFLAGS = -lvulkan +LDFLAGS = -lvulkan -lX11 $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) diff -r 68e1c437343f -r c31c4115d44a src/main.c --- a/src/main.c Fri Sep 22 01:01:10 2017 +0300 +++ b/src/main.c Fri Sep 22 15:26:29 2017 +0300 @@ -1,13 +1,45 @@ #include -#include +#include "wsys.h" #include "vku.h" +static void display(void); +static void reshape(int x, int y); +static void keyboard(int key, int pressed); + int main(void) { if(vku_create_dev() == -1) { - return -1; + return 1; } + if(wsys_create_window(800, 600) == -1) { + return 1; + } + wsys_set_window_title("Vulkan test 2"); + + wsys_display_callback(display); + wsys_reshape_callback(reshape); + wsys_keyboard_callback(keyboard); + + while(wsys_process_events(WSYS_BLOCKING) != -1); + + wsys_destroy_window(); vku_cleanup(); return 0; } + +static void display(void) +{ + wsys_swap_buffers(); +} + +static void reshape(int x, int y) +{ +} + +static void keyboard(int key, int pressed) +{ + if(key == 27) { + wsys_quit(); + } +} diff -r 68e1c437343f -r c31c4115d44a src/vku.c --- a/src/vku.c Fri Sep 22 01:01:10 2017 +0300 +++ b/src/vku.c Fri Sep 22 15:26:29 2017 +0300 @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "vku.h" static const char *get_device_name(VkPhysicalDeviceType type); @@ -12,26 +12,108 @@ static int ver_patch(uint32_t ver); static const char *mem_size_str(long sz); - VkInstance vk; VkDevice vkdev; VkQueue vkq; +static VkPhysicalDevice *phys_devices; +static int sel_dev, sel_qfamily; + +static VkExtensionProperties *vkext, *vkdevext; +static uint32_t vkext_count, vkdevext_count; + + +int vku_have_extension(const char *name) +{ + int i; + + if(!vkext) { + vkext_count = 0; + vkEnumerateInstanceExtensionProperties(0, &vkext_count, 0); + if(vkext_count) { + if(!(vkext = malloc(vkext_count * sizeof *vkext))) { + perror("failed to allocate instance extension list"); + return 0; + } + vkEnumerateInstanceExtensionProperties(0, &vkext_count, vkext); + + printf("instance extensions:\n"); + for(i=0; i<(int)vkext_count; i++) { + printf(" %s (ver: %u)\n", vkext[i].extensionName, (unsigned int)vkext[i].specVersion); + } + } + } + + for(i=0; i<(int)vkext_count; i++) { + if(strcmp(vkext[i].extensionName, name) == 0) { + return 1; + } + } + return 0; +} + +int vku_have_device_extension(const char *name) +{ + int i; + + if(sel_dev < 0) return 0; + + if(!vkdevext) { + vkdevext_count = 0; + vkEnumerateDeviceExtensionProperties(phys_devices[sel_dev], 0, &vkdevext_count, 0); + if(vkdevext_count) { + if(!(vkdevext = malloc(vkdevext_count * sizeof *vkdevext))) { + perror("failed to allocate device extension list"); + return 0; + } + vkEnumerateDeviceExtensionProperties(phys_devices[sel_dev], 0, &vkdevext_count, vkdevext); + + printf("selected device extensions:\n"); + for(i=0; i<(int)vkdevext_count; i++) { + printf(" %s (ver: %u)\n", vkdevext[i].extensionName, (unsigned int)vkdevext[i].specVersion); + } + } + } + + for(i=0; i<(int)vkdevext_count; i++) { + if(strcmp(vkdevext[i].extensionName, name) == 0) { + return 1; + } + } + return 0; +} + int vku_create_dev(void) { int i, j; VkInstanceCreateInfo inst_info; - VkPhysicalDevice *devices; VkDeviceCreateInfo dev_info; VkDeviceQueueCreateInfo queue_info; VkCommandPoolCreateInfo cmdpool_info; uint32_t num_devices; - int sel_dev = -1; - int sel_qfamily = -1; float qprio = 0.0f; + static const char *ext_names[] = { +#ifdef VK_USE_PLATFORM_XLIB_KHR + "VK_KHR_xlib_surface", +#endif + "VK_KHR_surface" + }; + + sel_dev = -1; + sel_qfamily = -1; + + for(i=0; ibuf, 0); @@ -183,6 +330,25 @@ } } +void vku_cmd_copybuf(VkCommandBuffer cmdbuf, VkBuffer dest, int doffs, + VkBuffer src, int soffs, int size) +{ + VkBufferCopy copy; + copy.size = size; + copy.srcOffset = soffs; + copy.dstOffset = doffs; + + vkCmdCopyBuffer(cmdbuf, src, dest, 1, ©); +} + +#ifdef VK_USE_PLATFORM_XLIB_KHR +int vku_xlib_usable_visual(Display *dpy, VisualID vid) +{ + return vkGetPhysicalDeviceXlibPresentationSupportKHR(phys_devices[sel_dev], + sel_qfamily, dpy, vid); +} +#endif /* VK_USE_PLATFORM_XLIB_KHR */ + static const char *get_device_name(VkPhysicalDeviceType type) { switch(type) { diff -r 68e1c437343f -r c31c4115d44a src/vku.h --- a/src/vku.h Fri Sep 22 01:01:10 2017 +0300 +++ b/src/vku.h Fri Sep 22 15:26:29 2017 +0300 @@ -1,24 +1,49 @@ #ifndef VKU_H_ #define VKU_H_ +#ifdef __unix__ +#define VK_USE_PLATFORM_XLIB_KHR +#endif + #include VkInstance vk; VkDevice vkdev; VkQueue vkq; VkCommandPool vkcmdpool; +VkCommandBuffer vkcmdbuf; /* primary command buffer */ -struct vk_buffer { +struct vku_buffer { VkBuffer buf; VkDeviceMemory mem_pool; int mem_start, mem_size; }; +int vku_have_extension(const char *name); +int vku_have_device_extension(const char *name); + int vku_create_dev(void); void vku_cleanup(void); +VkCommandBuffer vku_alloc_cmdbuf(VkCommandPool pool, VkCommandBufferLevel level); +void vku_free_cmdbuf(VkCommandPool pool, VkCommandBuffer buf); -struct vk_buffer *vku_create_buffer(int sz, unsigned int usage); -void vku_destroy_buffer(struct vk_buffer *buf); +void vku_begin_cmdbuf(VkCommandBuffer buf, unsigned int flags); +void vku_end_cmdbuf(VkCommandBuffer buf); +void vku_reset_cmdbuf(VkCommandBuffer buf); + +void vku_submit_cmdbuf(VkQueue q, VkCommandBuffer buf, VkFence done_fence); + +struct vku_buffer *vku_create_buffer(int sz, unsigned int usage); +void vku_destroy_buffer(struct vku_buffer *buf); + +void vku_cmd_copybuf(VkCommandBuffer cmdbuf, VkBuffer dest, int doffs, + VkBuffer src, int soffs, int size); + +/* platform-specific */ +#ifdef VK_USE_PLATFORM_XLIB_KHR +#include +int vku_xlib_usable_visual(Display *dpy, VisualID vid); +#endif #endif /* VKU_H_ */ diff -r 68e1c437343f -r c31c4115d44a src/wsys.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/wsys.h Fri Sep 22 15:26:29 2017 +0300 @@ -0,0 +1,31 @@ +#ifndef WSYS_H_ +#define WSYS_H_ + +/* pass to wsys_process_events */ +enum { + WSYS_BLOCKING = 0, + WSYS_NONBLOCK = 1 +}; + +int wsys_create_window(int xsz, int ysz); +void wsys_destroy_window(void); + +void wsys_set_window_title(const char *title); +void wsys_get_window_size(int *xsz, int *ysz); + +void wsys_display_callback(void (*func)(void)); +void wsys_reshape_callback(void (*func)(int, int)); +void wsys_keyboard_callback(void (*func)(int, int)); +void wsys_mouse_callback(void (*func)(int, int, int, int)); +void wsys_motion_callback(void (*func)(int, int)); +void wsys_passive_motion_callback(void (*func)(int, int)); + +void wsys_swap_buffers(void); +void wsys_redisplay(void); +void wsys_quit(void); + +/* mode: WSYS_BLOCKING or WSYS_NONBLOCK */ +int wsys_process_events(int mode); + + +#endif /* WSYS_H_ */ diff -r 68e1c437343f -r c31c4115d44a src/wsys_x11.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/wsys_x11.c Fri Sep 22 15:26:29 2017 +0300 @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include "wsys.h" +#include "vku.h" + +struct callbacks { + void (*display)(void); + void (*reshape)(int, int); + void (*keyboard)(int, int); + void (*mouse)(int, int, int, int); + void (*motion)(int, int); + void (*passive)(int, int); +}; + +enum { + QUIT = 1, + RESHAPE = 2, + REDISPLAY = 4 +}; + +static void proc_event(XEvent *ev); + +static Display *dpy; +static Window win; +static Atom xa_wm_delete; +static int win_width, win_height; +static int win_mapped; +static unsigned int evmask = StructureNotifyMask | ExposureMask; +static unsigned int pending; +static struct callbacks cb; + +int wsys_create_window(int xsz, int ysz) +{ + int i, scr, num_visuals; + Window root_win; + Visual *vis = 0; + XSetWindowAttributes xattr; + unsigned int xattr_mask; + XVisualInfo *vinf, vinf_match; + + if(!(dpy = XOpenDisplay(0))) { + fprintf(stderr, "failed to open connection to the X server\n"); + return -1; + } + scr = DefaultScreen(dpy); + root_win = RootWindow(dpy, scr); + + xa_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + + vinf_match.screen = scr; + vinf_match.depth = 24; + vinf_match.class = TrueColor; + + if(!(vinf = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &vinf_match, &num_visuals))) { + fprintf(stderr, "failed to retrieve matching visuals\n"); + XCloseDisplay(dpy); + return -1; + } + + for(i=0; itype) { + case MapNotify: + win_mapped = 1; + break; + + case UnmapNotify: + win_mapped = 0; + break; + + case ClientMessage: + if(ev->xclient.data.l[0] == xa_wm_delete) { + pending |= QUIT; + } + break; + + case ConfigureNotify: + if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) { + win_width = ev->xconfigure.width; + win_height = ev->xconfigure.height; + pending |= RESHAPE; + } + break; + + case Expose: + if(ev->xexpose.count == 0) { + pending |= REDISPLAY; + } + break; + + case KeyPress: + case KeyRelease: + if(cb.keyboard) { + KeySym sym; + char str[16]; + XLookupString(&ev->xkey, str, sizeof str, &sym, 0); + cb.keyboard(sym & 0xff, ev->type == KeyPress ? 1 : 0); + } + break; + + case ButtonPress: + case ButtonRelease: + if(cb.mouse) { + int bn = ev->xbutton.button - Button1; + int pressed = ev->type == ButtonPress ? 1 : 0; + cb.mouse(bn, pressed, ev->xbutton.x, ev->xbutton.y); + } + break; + + case MotionNotify: + if(ev->xmotion.state & 0x1f00) { + if(cb.motion) { + cb.motion(ev->xmotion.x, ev->xmotion.y); + } + } else { + if(cb.passive) { + cb.passive(ev->xmotion.x, ev->xmotion.y); + } + } + break; + } +}