mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2026-01-16 06:04:07 +00:00
move
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@110 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
69
src/widget/button.c
Normal file
69
src/widget/button.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
static void create(MwWidget handle) {
|
||||
MwSetDefault(handle);
|
||||
}
|
||||
|
||||
static void draw(MwWidget handle) {
|
||||
MwRect r;
|
||||
MwPoint point;
|
||||
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
|
||||
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground));
|
||||
const char* str = MwGetText(handle, MwNtext);
|
||||
MwLLPixmap px = MwGetVoid(handle, MwNpixmap);
|
||||
|
||||
if(str == NULL) str = "";
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = MwGetInteger(handle, MwNwidth);
|
||||
r.height = MwGetInteger(handle, MwNheight);
|
||||
|
||||
MwDrawFrame(handle, &r, base, handle->pressed);
|
||||
MwDrawRect(handle, &r, base);
|
||||
|
||||
if(px != NULL) {
|
||||
int ow = r.width;
|
||||
int oh = r.height;
|
||||
|
||||
double sw = (double)ow / px->width;
|
||||
double sh = (double)oh / px->height;
|
||||
|
||||
if(sw < sh) {
|
||||
r.width = px->width * sw;
|
||||
r.height = px->height * sw;
|
||||
} else {
|
||||
r.width = px->width * sh;
|
||||
r.height = px->height * sh;
|
||||
}
|
||||
r.width -= 10;
|
||||
r.height -= 10;
|
||||
|
||||
r.x += (double)(ow - r.width) / 2;
|
||||
r.y += (double)(oh - r.height) / 2;
|
||||
|
||||
MwLLDrawPixmap(handle->lowlevel, &r, px);
|
||||
} else {
|
||||
point.x = r.x + r.width / 2;
|
||||
point.y = r.x + r.height / 2;
|
||||
|
||||
MwDrawText(handle, &point, str, 0, text);
|
||||
}
|
||||
|
||||
MwLLFreeColor(text);
|
||||
MwLLFreeColor(base);
|
||||
}
|
||||
|
||||
static void click(MwWidget handle) {
|
||||
MwDispatchUserHandler(handle, MwNactivateHandler, NULL);
|
||||
}
|
||||
|
||||
MwClassRec MwButtonClassRec = {
|
||||
create, /* create */
|
||||
NULL, /* destroy */
|
||||
draw, /* draw */
|
||||
click, /* click */
|
||||
NULL /* parent_resize */
|
||||
};
|
||||
MwClass MwButtonClass = &MwButtonClassRec;
|
||||
31
src/widget/frame.c
Normal file
31
src/widget/frame.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
static void create(MwWidget handle) {
|
||||
MwSetDefault(handle);
|
||||
}
|
||||
|
||||
static void draw(MwWidget handle) {
|
||||
MwRect r;
|
||||
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = MwGetInteger(handle, MwNwidth);
|
||||
r.height = MwGetInteger(handle, MwNheight);
|
||||
|
||||
MwDrawFrameEx(handle, &r, base, 1, 1);
|
||||
MwDrawFrameEx(handle, &r, base, 0, 1);
|
||||
MwDrawRect(handle, &r, base);
|
||||
|
||||
MwLLFreeColor(base);
|
||||
}
|
||||
|
||||
MwClassRec MwFrameClassRec = {
|
||||
create, /* create */
|
||||
NULL, /* destroy */
|
||||
draw, /* draw */
|
||||
NULL, /* click */
|
||||
NULL /* parent_resize */
|
||||
};
|
||||
MwClass MwFrameClass = &MwFrameClassRec;
|
||||
139
src/widget/menu.c
Normal file
139
src/widget/menu.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
#include "../external/stb_ds.h"
|
||||
|
||||
typedef struct menu menu_t;
|
||||
|
||||
struct menu {
|
||||
char* name;
|
||||
menu_t** sub;
|
||||
};
|
||||
|
||||
static void set_xywh(MwWidget handle) {
|
||||
int height = 0;
|
||||
int i;
|
||||
menu_t* m = handle->internal;
|
||||
|
||||
for(i = 0; i < arrlen(m->sub); i++) {
|
||||
int h = MwTextHeight(handle, m->sub[i]->name);
|
||||
if(height < h) {
|
||||
height = h;
|
||||
}
|
||||
}
|
||||
|
||||
height += 20;
|
||||
|
||||
MwVaApply(handle,
|
||||
MwNx, 0,
|
||||
MwNy, 0,
|
||||
MwNwidth, MwGetInteger(handle->parent, MwNwidth),
|
||||
MwNheight, height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void create(MwWidget handle) {
|
||||
menu_t* m = malloc(sizeof(*m));
|
||||
|
||||
m->name = NULL;
|
||||
m->sub = NULL;
|
||||
handle->internal = m;
|
||||
|
||||
MwSetDefault(handle);
|
||||
|
||||
set_xywh(handle);
|
||||
}
|
||||
|
||||
static void recursive_free(menu_t* m) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < arrlen(m->sub); i++) {
|
||||
recursive_free(m->sub[i]);
|
||||
}
|
||||
|
||||
if(m->sub != NULL) arrfree(m->sub);
|
||||
if(m->name != NULL) free(m->name);
|
||||
free(m);
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
menu_t* m = handle->internal;
|
||||
|
||||
recursive_free(m);
|
||||
}
|
||||
|
||||
static void draw(MwWidget handle) {
|
||||
MwRect r;
|
||||
MwPoint p;
|
||||
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
|
||||
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground));
|
||||
menu_t* m = handle->internal;
|
||||
int i;
|
||||
|
||||
p.x = 10;
|
||||
p.y = MwGetInteger(handle, MwNheight) / 2;
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = MwGetInteger(handle, MwNwidth);
|
||||
r.height = MwGetInteger(handle, MwNheight);
|
||||
|
||||
MwDrawFrame(handle, &r, base, 0);
|
||||
MwDrawRect(handle, &r, base);
|
||||
for(i = 0; i < arrlen(m->sub); i++) {
|
||||
int incr = m->sub[i]->name[0] == '?' ? 1 : 0;
|
||||
int tw = MwTextWidth(handle, m->sub[i]->name + incr);
|
||||
int th = MwTextHeight(handle, m->sub[i]->name + incr);
|
||||
int oldx = p.x;
|
||||
|
||||
if(incr) {
|
||||
p.x = MwGetInteger(handle, MwNwidth) - tw - 10;
|
||||
}
|
||||
p.x += tw / 2;
|
||||
|
||||
r.x = p.x - tw / 2 - 5;
|
||||
r.y = p.y - th / 2 - 5;
|
||||
r.width = tw + 10;
|
||||
r.height = th + 10;
|
||||
|
||||
if(handle->pressed && r.x <= handle->pressed_point.x && r.y <= handle->pressed_point.y && handle->pressed_point.x <= (int)(r.x + r.width) && handle->pressed_point.y <= (int)(r.y + r.height)) {
|
||||
MwDrawFrame(handle, &r, base, 0);
|
||||
}
|
||||
|
||||
MwDrawText(handle, &p, m->sub[i]->name + incr, 1, text);
|
||||
|
||||
p.x += tw / 2 + 20;
|
||||
if(incr) p.x = oldx;
|
||||
}
|
||||
|
||||
MwLLFreeColor(text);
|
||||
MwLLFreeColor(base);
|
||||
}
|
||||
|
||||
static void parent_resize(MwWidget handle) {
|
||||
set_xywh(handle);
|
||||
}
|
||||
|
||||
MwClassRec MwMenuClassRec = {
|
||||
create, /* create */
|
||||
destroy, /* destroy */
|
||||
draw, /* draw */
|
||||
NULL, /* click */
|
||||
parent_resize /* parent_resize */
|
||||
};
|
||||
MwClass MwMenuClass = &MwMenuClassRec;
|
||||
|
||||
void* MwMenuAdd(MwWidget handle, void* menu, const char* name) {
|
||||
menu_t* m = menu == NULL ? handle->internal : menu;
|
||||
menu_t* new = malloc(sizeof(*new));
|
||||
new->name = malloc(strlen(name) + 1);
|
||||
new->sub = NULL;
|
||||
|
||||
strcpy(new->name, name);
|
||||
|
||||
arrput(m->sub, new);
|
||||
|
||||
set_xywh(handle);
|
||||
|
||||
return new;
|
||||
}
|
||||
169
src/widget/opengl.c
Normal file
169
src/widget/opengl.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
#include <Mw/OpenGL.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* nothing */
|
||||
#else
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#include <GL/gl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef HGLRC(WINAPI* MWwglCreateContext)(HDC);
|
||||
typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC);
|
||||
typedef PROC(WINAPI* MWwglGetProcAddress)(LPCSTR);
|
||||
typedef BOOL(WINAPI* MWwglDeleteContext)(HGLRC);
|
||||
|
||||
typedef struct opengl {
|
||||
HDC dc;
|
||||
HGLRC gl;
|
||||
|
||||
void* lib;
|
||||
|
||||
MWwglCreateContext wglCreateContext;
|
||||
MWwglMakeCurrent wglMakeCurrent;
|
||||
MWwglDeleteContext wglDeleteContext;
|
||||
MWwglGetProcAddress wglGetProcAddress;
|
||||
} opengl_t;
|
||||
#else
|
||||
typedef XVisualInfo* (*MWglXChooseVisual)(Display* dpy, int screen, int* attribList);
|
||||
typedef GLXContext (*MWglXCreateContext)(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct);
|
||||
typedef void (*MWglXDestroyContext)(Display* dpy, GLXContext ctx);
|
||||
typedef Bool (*MWglXMakeCurrent)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
|
||||
typedef void (*MWglXSwapBuffers)(Display* dpy, GLXDrawable drawable);
|
||||
typedef void* (*MWglXGetProcAddress)(const GLubyte* procname);
|
||||
|
||||
typedef struct opengl {
|
||||
XVisualInfo* visual;
|
||||
GLXContext gl;
|
||||
|
||||
void* lib;
|
||||
|
||||
MWglXChooseVisual glXChooseVisual;
|
||||
MWglXCreateContext glXCreateContext;
|
||||
MWglXDestroyContext glXDestroyContext;
|
||||
MWglXMakeCurrent glXMakeCurrent;
|
||||
MWglXSwapBuffers glXSwapBuffers;
|
||||
MWglXGetProcAddress glXGetProcAddress;
|
||||
} opengl_t;
|
||||
#endif
|
||||
|
||||
static void create(MwWidget handle) {
|
||||
opengl_t* o = malloc(sizeof(*o));
|
||||
#ifdef _WIN32
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int pf;
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.cDepthBits = 32;
|
||||
pfd.cColorBits = 32;
|
||||
|
||||
o->dc = GetDC(handle->lowlevel->hWnd);
|
||||
|
||||
pf = ChoosePixelFormat(o->dc, &pfd);
|
||||
SetPixelFormat(o->dc, pf, &pfd);
|
||||
|
||||
o->lib = LoadLibrary("opengl32.dll");
|
||||
|
||||
o->wglCreateContext = (MWwglCreateContext)(void*)GetProcAddress(o->lib, "wglCreateContext");
|
||||
o->wglMakeCurrent = (MWwglMakeCurrent)(void*)GetProcAddress(o->lib, "wglMakeCurrent");
|
||||
o->wglDeleteContext = (MWwglDeleteContext)(void*)GetProcAddress(o->lib, "wglDeleteContext");
|
||||
o->wglGetProcAddress = (MWwglGetProcAddress)(void*)GetProcAddress(o->lib, "wglGetProcAddress");
|
||||
|
||||
o->gl = o->wglCreateContext(o->dc);
|
||||
#else
|
||||
int attribs[5];
|
||||
const char* glpath[] = {
|
||||
"libGL.so",
|
||||
"/usr/local/lib/libGL.so",
|
||||
"/usr/X11R7/lib/libGL.so",
|
||||
"/usr/pkg/lib/libGL.so"};
|
||||
int glincr = 0;
|
||||
|
||||
attribs[0] = GLX_RGBA;
|
||||
attribs[1] = GLX_DOUBLEBUFFER;
|
||||
attribs[2] = GLX_DEPTH_SIZE;
|
||||
attribs[3] = 24;
|
||||
attribs[4] = None;
|
||||
|
||||
while(glpath[glincr] != NULL && (o->lib = dlopen(glpath[glincr++], RTLD_LAZY)) == NULL);
|
||||
|
||||
o->glXChooseVisual = (MWglXChooseVisual)dlsym(o->lib, "glXChooseVisual");
|
||||
o->glXCreateContext = (MWglXCreateContext)dlsym(o->lib, "glXCreateContext");
|
||||
o->glXDestroyContext = (MWglXDestroyContext)dlsym(o->lib, "glXDestroyContext");
|
||||
o->glXMakeCurrent = (MWglXMakeCurrent)dlsym(o->lib, "glXMakeCurrent");
|
||||
o->glXSwapBuffers = (MWglXSwapBuffers)dlsym(o->lib, "glXSwapBuffers");
|
||||
o->glXGetProcAddress = (MWglXGetProcAddress)dlsym(o->lib, "glXGetProcAddress");
|
||||
|
||||
/* XXX: fix this */
|
||||
o->visual = o->glXChooseVisual(handle->lowlevel->display, DefaultScreen(handle->lowlevel->display), attribs);
|
||||
o->gl = o->glXCreateContext(handle->lowlevel->display, o->visual, NULL, GL_TRUE);
|
||||
#endif
|
||||
handle->internal = o;
|
||||
handle->lowlevel->copy_buffer = 0;
|
||||
|
||||
MwSetDefault(handle);
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
opengl_t* o = (opengl_t*)handle->internal;
|
||||
#ifdef _WIN32
|
||||
o->wglMakeCurrent(NULL, NULL);
|
||||
DeleteDC(o->dc);
|
||||
o->wglDeleteContext(o->gl);
|
||||
|
||||
FreeLibrary(o->lib);
|
||||
#else
|
||||
o->glXMakeCurrent(handle->lowlevel->display, None, NULL);
|
||||
o->glXDestroyContext(handle->lowlevel->display, o->gl);
|
||||
|
||||
dlclose(o->lib);
|
||||
#endif
|
||||
free(o);
|
||||
}
|
||||
|
||||
MwClassRec MwOpenGLClassRec = {
|
||||
create, /* create */
|
||||
destroy, /* destroy */
|
||||
NULL, /* draw */
|
||||
NULL, /* click */
|
||||
NULL /* parent_resize */
|
||||
};
|
||||
MwClass MwOpenGLClass = &MwOpenGLClassRec;
|
||||
|
||||
void MwOpenGLMakeCurrent(MwWidget handle) {
|
||||
opengl_t* o = (opengl_t*)handle->internal;
|
||||
#ifdef _WIN32
|
||||
o->wglMakeCurrent(o->dc, o->gl);
|
||||
#else
|
||||
o->glXMakeCurrent(handle->lowlevel->display, handle->lowlevel->window, o->gl);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MwOpenGLSwapBuffer(MwWidget handle) {
|
||||
opengl_t* o = (opengl_t*)handle->internal;
|
||||
#ifdef _WIN32
|
||||
SwapBuffers(o->dc);
|
||||
#else
|
||||
(void)o;
|
||||
|
||||
o->glXSwapBuffers(handle->lowlevel->display, handle->lowlevel->window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void* MwOpenGLGetProcAddress(MwWidget handle, const char* name) {
|
||||
opengl_t* o = (opengl_t*)handle->internal;
|
||||
#ifdef _WIN32
|
||||
(void)handle;
|
||||
|
||||
return o->wglGetProcAddress(name);
|
||||
#else
|
||||
(void)handle;
|
||||
|
||||
return o->glXGetProcAddress((const GLubyte*)name);
|
||||
#endif
|
||||
}
|
||||
385
src/widget/vulkan.c
Normal file
385
src/widget/vulkan.c
Normal file
@@ -0,0 +1,385 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
#include <Mw/Vulkan.h>
|
||||
|
||||
/**
|
||||
* ioixd maintains this file. nishi doesn't know vulkan at all
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define VK_USE_PLATFORM_WIN32_KHR 1
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#define VK_USE_PLATFORM_XLIB_KHR 1
|
||||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
#ifdef __linux__
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "stb_ds.h"
|
||||
|
||||
// convienence macro for handling vulkan errors
|
||||
#define VK_CMD(func) \
|
||||
vk_res = func; \
|
||||
if(vk_res != VK_SUCCESS) { \
|
||||
printf("VULKAN ERROR AT %s:%d: %s\n", __FILE__, __LINE__, string_VkResult(vk_res)); \
|
||||
exit(0); \
|
||||
}
|
||||
|
||||
// convienence macro for loading a vulkan function pointer into memory
|
||||
#define LOAD_VK_FUNCTION(name) \
|
||||
PFN_##name _##name = (PFN_##name)o->vkGetInstanceProcAddr(o->vkInstance, #name); \
|
||||
assert(_##name);
|
||||
|
||||
bool enableValidationLayers = true;
|
||||
|
||||
const char** enabledExtensions;
|
||||
unsigned int enabledExtensionCount = 0;
|
||||
|
||||
typedef struct vulkan {
|
||||
void* vulkanLibrary;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
|
||||
VkInstance vkInstance;
|
||||
VkSurfaceKHR vkSurface;
|
||||
|
||||
VkPhysicalDevice vkPhysicalDevice;
|
||||
VkDevice vkLogicalDevice;
|
||||
VkQueue vkGraphicsQueue;
|
||||
VkQueue vkPresentQueue;
|
||||
uint32_t vkGraphicsFamilyIDX;
|
||||
uint32_t vkPresentFamilyIDX;
|
||||
|
||||
const char** vkInstanceExtensions;
|
||||
const char** vkDeviceExtensions;
|
||||
const char** vkLayers;
|
||||
int vkInstanceExtensionCount;
|
||||
int vkDeviceExtensionCount;
|
||||
int vkLayerCount;
|
||||
} vulkan_t;
|
||||
|
||||
static void vulkan_instance_setup(MwWidget handle, vulkan_t* o);
|
||||
static void vulkan_surface_setup(MwWidget handle, vulkan_t* o);
|
||||
static void vulkan_devices_setup(MwWidget handle, vulkan_t* o);
|
||||
|
||||
static void create(MwWidget handle) {
|
||||
vulkan_t* o = malloc(sizeof(*o));
|
||||
|
||||
// !! important to call it in this order
|
||||
vulkan_instance_setup(handle, o);
|
||||
vulkan_surface_setup(handle, o);
|
||||
vulkan_devices_setup(handle, o);
|
||||
|
||||
handle->internal = o;
|
||||
MwSetDefault(handle);
|
||||
}
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
vulkan_t* o = (vulkan_t*)handle->internal;
|
||||
free(o);
|
||||
}
|
||||
|
||||
static void vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
|
||||
// todo: Some sort of function for being able to set the vulkan version?
|
||||
uint32_t vulkan_version = VK_VERSION_1_0;
|
||||
uint32_t api_version = VK_API_VERSION_1_0;
|
||||
uint32_t extension_count = 0;
|
||||
uint32_t layer_count = 0;
|
||||
unsigned long i, n = 0;
|
||||
|
||||
(void)handle;
|
||||
(void)o;
|
||||
|
||||
PFN_vkEnumerateInstanceExtensionProperties
|
||||
_vkEnumerateInstanceExtensionProperties;
|
||||
PFN_vkEnumerateInstanceLayerProperties _vkEnumerateInstanceLayerProperties;
|
||||
PFN_vkCreateInstance _vkCreateInstance;
|
||||
|
||||
VkApplicationInfo app_info;
|
||||
VkInstanceCreateInfo instance_create_info;
|
||||
|
||||
VkExtensionProperties* ext_props;
|
||||
VkLayerProperties* layer_props;
|
||||
|
||||
VkResult vk_res;
|
||||
|
||||
// TODO: support for whatever win32's equivalants to dlopen/dlsym are
|
||||
o->vulkanLibrary = dlopen("libvulkan.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
o->vkGetInstanceProcAddr = dlsym(o->vulkanLibrary, "vkGetInstanceProcAddr");
|
||||
assert(o->vkGetInstanceProcAddr);
|
||||
|
||||
// Load in any other function pointers we need.
|
||||
_vkEnumerateInstanceExtensionProperties = dlsym(o->vulkanLibrary, "vkEnumerateInstanceExtensionProperties");
|
||||
assert(_vkEnumerateInstanceExtensionProperties);
|
||||
_vkEnumerateInstanceLayerProperties = dlsym(o->vulkanLibrary, "vkEnumerateInstanceLayerProperties");
|
||||
assert(_vkEnumerateInstanceLayerProperties);
|
||||
_vkCreateInstance = dlsym(o->vulkanLibrary, "vkCreateInstance");
|
||||
assert(_vkCreateInstance);
|
||||
|
||||
// setup enabled extensions
|
||||
arrput(enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
#if defined(_WIN32)
|
||||
arrput(enabledExtensions, VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
arrput(enabledExtensions, VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
|
||||
// passing null gives us all the extensions provided by the current vulkan implementation
|
||||
VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, NULL));
|
||||
ext_props = malloc(sizeof(VkExtensionProperties) * extension_count);
|
||||
VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, ext_props));
|
||||
o->vkInstanceExtensions = malloc(sizeof(const char*) * (arrlen(enabledExtensions) + 1));
|
||||
|
||||
for(i = 0; i < extension_count; i++) {
|
||||
for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) {
|
||||
if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) {
|
||||
o->vkInstanceExtensions[o->vkInstanceExtensionCount] = ext_props[i].extensionName;
|
||||
o->vkInstanceExtensionCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("enabled %d instance extensions\n", o->vkInstanceExtensionCount);
|
||||
|
||||
app_info = (VkApplicationInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = NULL,
|
||||
.pApplicationName = "",
|
||||
.applicationVersion = vulkan_version,
|
||||
.pEngineName = "",
|
||||
.engineVersion = vulkan_version,
|
||||
.apiVersion = api_version,
|
||||
};
|
||||
|
||||
VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, NULL));
|
||||
layer_props = malloc(sizeof(VkLayerProperties) * layer_count);
|
||||
VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, layer_props));
|
||||
o->vkLayers = malloc(256 * (layer_count + 2));
|
||||
for(i = 0; i < layer_count; i++) {
|
||||
if(enableValidationLayers) {
|
||||
if(strcmp(layer_props[i].layerName, "VK_LAYER_KHRONOS_validation") == 0) {
|
||||
printf("layer: %s\n", layer_props[i].layerName);
|
||||
memset(&o->vkLayers[i], 0, 255);
|
||||
memcpy(&o->vkLayers[i], layer_props[i].layerName, 254);
|
||||
o->vkLayerCount++;
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
o->vkLayers[i++] = NULL;
|
||||
|
||||
instance_create_info = (VkInstanceCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.pApplicationInfo = &app_info,
|
||||
.enabledExtensionCount = o->vkInstanceExtensionCount,
|
||||
.enabledLayerCount = 0,
|
||||
.ppEnabledExtensionNames = o->vkInstanceExtensions,
|
||||
.ppEnabledLayerNames = o->vkLayers,
|
||||
};
|
||||
instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
|
||||
VK_CMD(_vkCreateInstance(&instance_create_info, NULL, &o->vkInstance));
|
||||
}
|
||||
|
||||
static void vulkan_surface_setup(MwWidget handle, vulkan_t* o) {
|
||||
int vk_res;
|
||||
#ifdef _WIN32
|
||||
LOAD_VK_FUNCTION(vkCreateWin32SurfaceKHR);
|
||||
|
||||
VkWin32SurfaceCreateInfoKHR createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.hinstance = handle->lowlevel->hInstance,
|
||||
.hwnd = handle->lowlevel->hWnd,
|
||||
};
|
||||
|
||||
VK_CMD(_vkCreateWin32SurfaceKHR(o->vkInstance, &createInfo, NULL,
|
||||
&o->vkSurface));
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
LOAD_VK_FUNCTION(vkCreateXlibSurfaceKHR);
|
||||
|
||||
VkXlibSurfaceCreateInfoKHR createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.dpy = handle->lowlevel->display,
|
||||
.window = handle->lowlevel->window,
|
||||
};
|
||||
VK_CMD(_vkCreateXlibSurfaceKHR(o->vkInstance, &createInfo, NULL, &o->vkSurface));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vulkan_devices_setup(MwWidget handle, vulkan_t* o) {
|
||||
int vk_res;
|
||||
unsigned long i, n;
|
||||
uint32_t deviceCount;
|
||||
VkPhysicalDevice* devices;
|
||||
uint32_t queueFamilyCount;
|
||||
VkQueueFamilyProperties* family_props;
|
||||
float queuePriority = 1.0f;
|
||||
VkDeviceQueueCreateInfo queueCreateInfos[2];
|
||||
VkDeviceCreateInfo createInfo;
|
||||
VkExtensionProperties* ext_props;
|
||||
uint32_t extension_count;
|
||||
VkBool32 has_graphics = false;
|
||||
VkBool32 has_present = false;
|
||||
int queueCreateCount = 0;
|
||||
|
||||
(void)handle;
|
||||
|
||||
LOAD_VK_FUNCTION(vkEnumeratePhysicalDevices);
|
||||
LOAD_VK_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties);
|
||||
LOAD_VK_FUNCTION(vkCreateDevice);
|
||||
LOAD_VK_FUNCTION(vkGetDeviceQueue);
|
||||
LOAD_VK_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR);
|
||||
|
||||
PFN_vkEnumerateDeviceExtensionProperties _vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)
|
||||
o->vkGetInstanceProcAddr(o->vkInstance, "vkEnumerateDeviceExtensionProperties");
|
||||
assert(_vkEnumerateDeviceExtensionProperties);
|
||||
|
||||
// create the physical device
|
||||
VK_CMD(_vkEnumeratePhysicalDevices(o->vkInstance, &deviceCount, NULL));
|
||||
devices = malloc(sizeof(VkPhysicalDevice) * deviceCount);
|
||||
VK_CMD(_vkEnumeratePhysicalDevices(o->vkInstance, &deviceCount, devices));
|
||||
|
||||
for(i = 0; i < deviceCount; i++) {
|
||||
_vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &queueFamilyCount, NULL);
|
||||
family_props = malloc(sizeof(VkQueueFamilyProperties) * queueFamilyCount);
|
||||
_vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &queueFamilyCount, family_props);
|
||||
o->vkGraphicsFamilyIDX = 0;
|
||||
o->vkPresentFamilyIDX = 0;
|
||||
for(n = 0; n < queueFamilyCount; n++) {
|
||||
if(family_props[n].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
has_graphics = true;
|
||||
o->vkGraphicsFamilyIDX = n;
|
||||
};
|
||||
|
||||
_vkGetPhysicalDeviceSurfaceSupportKHR(devices[i], n, o->vkSurface,
|
||||
&has_present);
|
||||
if(has_present) {
|
||||
o->vkPresentFamilyIDX = n;
|
||||
}
|
||||
if(has_graphics && has_present) {
|
||||
o->vkPhysicalDevice = devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(family_props);
|
||||
}
|
||||
if(!has_graphics && !has_present) {
|
||||
// rare, yes, but idk maybe some shitty drivers will present this dillema idk.
|
||||
printf("There were no devices with either a graphics or presentation queue. Exiting!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create the logical device
|
||||
queueCreateInfos[queueCreateCount] = (VkDeviceQueueCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.queueFamilyIndex = o->vkGraphicsFamilyIDX,
|
||||
.queueCount = 1,
|
||||
.pQueuePriorities = &queuePriority,
|
||||
};
|
||||
if(o->vkGraphicsFamilyIDX == o->vkPresentFamilyIDX) {
|
||||
queueCreateInfos[queueCreateCount++] = (VkDeviceQueueCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.queueFamilyIndex = o->vkPresentFamilyIDX,
|
||||
.queueCount = 1,
|
||||
.pQueuePriorities = &queuePriority,
|
||||
};
|
||||
}
|
||||
|
||||
VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, NULL));
|
||||
ext_props = malloc(sizeof(VkExtensionProperties) * extension_count);
|
||||
VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, ext_props));
|
||||
o->vkDeviceExtensions = malloc(sizeof(const char*) * (arrlen(enabledExtensions) + 1));
|
||||
|
||||
for(i = 0; i < extension_count; i++) {
|
||||
for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) {
|
||||
if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) {
|
||||
o->vkDeviceExtensions[o->vkDeviceExtensionCount] = ext_props[i].extensionName;
|
||||
o->vkDeviceExtensionCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("enabled %d device extensions\n", o->vkDeviceExtensionCount);
|
||||
|
||||
createInfo = (VkDeviceCreateInfo){
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.queueCreateInfoCount = queueCreateCount,
|
||||
.pQueueCreateInfos = queueCreateInfos,
|
||||
.pEnabledFeatures = NULL,
|
||||
.enabledExtensionCount = o->vkDeviceExtensionCount,
|
||||
.ppEnabledExtensionNames = o->vkDeviceExtensions,
|
||||
.enabledLayerCount = 0,
|
||||
.ppEnabledLayerNames = NULL,
|
||||
};
|
||||
|
||||
VK_CMD(_vkCreateDevice(o->vkPhysicalDevice, &createInfo, NULL, &o->vkLogicalDevice) != VK_SUCCESS);
|
||||
|
||||
_vkGetDeviceQueue(o->vkLogicalDevice, o->vkGraphicsFamilyIDX, 0, &o->vkGraphicsQueue);
|
||||
if(o->vkGraphicsFamilyIDX == o->vkPresentFamilyIDX) {
|
||||
o->vkPresentQueue = o->vkGraphicsQueue;
|
||||
} else {
|
||||
_vkGetDeviceQueue(o->vkLogicalDevice, o->vkPresentFamilyIDX, 0, &o->vkPresentQueue);
|
||||
}
|
||||
// free(devices);
|
||||
}
|
||||
|
||||
void MwVulkanEnableExtension(const char* name) {
|
||||
arrput(enabledExtensions, name);
|
||||
}
|
||||
|
||||
PFN_vkGetInstanceProcAddr MwVulkanGetInstanceProcAddr(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkGetInstanceProcAddr;
|
||||
};
|
||||
VkInstance MwVulkanGetInstance(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkInstance;
|
||||
};
|
||||
VkSurfaceKHR MwVulkanGetSurface(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkSurface;
|
||||
};
|
||||
VkPhysicalDevice MwVulkanGetPhysicalDevice(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkPhysicalDevice;
|
||||
};
|
||||
VkDevice MwVulkanGetLogicalDevice(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkLogicalDevice;
|
||||
};
|
||||
VkQueue MwVulkanGetGraphicsQueue(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkGraphicsQueue;
|
||||
};
|
||||
VkQueue MwVulkanGetPresentQueue(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkPresentQueue;
|
||||
};
|
||||
|
||||
int MwVulkanGetGraphicsQueueIndex(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkGraphicsFamilyIDX;
|
||||
}
|
||||
|
||||
int MwVulkanGetPresentQueueIndex(MwWidget handle) {
|
||||
return ((vulkan_t*)handle->internal)->vkPresentFamilyIDX;
|
||||
}
|
||||
|
||||
MwClassRec MwVulkanClassRec = {
|
||||
create, /* create */
|
||||
destroy, /* destroy */
|
||||
NULL, /* draw */
|
||||
NULL, /* click */
|
||||
NULL /* parent_resize */
|
||||
};
|
||||
MwClass MwVulkanClass = &MwVulkanClassRec;
|
||||
33
src/widget/window.c
Normal file
33
src/widget/window.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
static void create(MwWidget handle) {
|
||||
MwSetDefault(handle);
|
||||
}
|
||||
|
||||
static void draw(MwWidget handle) {
|
||||
MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground));
|
||||
MwRect r;
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = MwGetInteger(handle, MwNwidth);
|
||||
r.height = MwGetInteger(handle, MwNheight);
|
||||
|
||||
MwDrawRect(handle, &r, c);
|
||||
|
||||
MwLLFreeColor(c);
|
||||
}
|
||||
|
||||
MwClassRec MwWindowClassRec = {
|
||||
create, /* create */
|
||||
NULL, /* destroy */
|
||||
draw, /* draw */
|
||||
NULL, /* click */
|
||||
NULL /* parent_resize */
|
||||
};
|
||||
MwClass MwWindowClass = &MwWindowClassRec;
|
||||
|
||||
void MwWindowSetIcon(MwWidget handle, MwLLPixmap pixmap) {
|
||||
MwLLSetIcon(handle->lowlevel, pixmap);
|
||||
}
|
||||
Reference in New Issue
Block a user