УУУПС X)
This commit is contained in:
parent
fc7884a9ed
commit
a1807a4dfa
@ -397,10 +397,10 @@ NODISCARD VecU8 generate_OptionT_struct_and_methods(SpanU8 T, bool primitive, bo
|
||||
SPACE4 "%s some;\n"
|
||||
"} %s;\n\n", T, OptionT);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"#define None_%s() (%s){ .variant = Option_None }\n"
|
||||
"#define Some_%s(expr) (%s){ .variant = Option_Some, .some = (expr) }\n\n",
|
||||
T, OptionT, T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() (%s){ .variant = Option_None }\n\n", T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s Some_%s(obj) {\n"
|
||||
SPACE4 "(%s){ .variant = Option_Some, .some = obj };\n"
|
||||
"}\n\n", OptionT, T, OptionT));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"const %s* %s_expect_ref(const %s* self){\n"
|
||||
|
||||
@ -26,7 +26,7 @@ void eve_of_l2() {
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("ModelOnScene"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("UsedModelOnScene"), true, false);
|
||||
/* Needed in margaret/vulkan.h */
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("Xlib_Event"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("Xlib_Event"), true, false); // todo: get rid of this crap
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("CSTR"), true, false);
|
||||
// generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("MargaretChosenQueueFamilies"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkQueueFamilyProperties"), true, false);
|
||||
@ -35,6 +35,10 @@ void eve_of_l2() {
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .option = true });
|
||||
generate_eve_header(cstr("l2"), cstr(""), cstr("VkPresentModeKHR"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .option = true });
|
||||
generate_eve_header(cstr("l2"), cstr(""), cstr("VkCompositeAlphaFlagBitsKHR"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .option = true });
|
||||
generate_eve_header(cstr("l2"), cstr(""), cstr("VkExtent2D"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .option = true });
|
||||
generate_eve_header(cstr("l2"), cstr(""), cstr("VkFormat"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .span = true, .option = true });
|
||||
generate_eve_header(cstr("l2"), cstr(""), cstr("MargaretScoredPhysicalDevice"),
|
||||
|
||||
@ -3,94 +3,13 @@
|
||||
|
||||
#include "../../../gen/l1/Option_int_primitives.h"
|
||||
#include "../../../gen/l1/VecAndSpan_Vec_int_primitives.h"
|
||||
// todo: rewrite this crap to wayland (fom now on wayland is my best friend in all situations)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
#include <vulkan/vulkan_wayland.h>
|
||||
#include "../core/stringop.h"
|
||||
#include "../../l1/system/fileio.h"
|
||||
#include "time.h"
|
||||
#include <wayland-client.h>
|
||||
|
||||
// todo: rewrite margaret to use libwayland-client, and get rid of this fucking crap
|
||||
typedef XEvent Xlib_Event;
|
||||
|
||||
#include "../../../gen/l2/eve/VecXlib_Event.h"
|
||||
|
||||
// todo: AAAAAAAAAAAAA I HATE XLIB SO FUCKINGG MNJUHC AAAASAAAAA AAAAAAA
|
||||
typedef Display Xlib_Display;
|
||||
typedef Window Xlib_Window;
|
||||
typedef Atom Xlib_Atom;
|
||||
|
||||
// todo: AAAAAAAAAAAAAAAA AAASASDASDASDASDAGAHGFKJG AAAAAAAAAAA FUCK XLIB FUCK XORG FUCK THIS SHIT
|
||||
NODISCARD VecXlib_Event margaret_read_x_events(Xlib_Display* dpy) {
|
||||
int evh = XEventsQueued(dpy, QueuedAfterReading);
|
||||
VecXlib_Event result = VecXlib_Event_new_zeroinit(evh);
|
||||
for (int i = 0; i < evh; i++) {
|
||||
XNextEvent(dpy, VecXlib_Event_mat(&result, i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void margaret_win_init_set_properties(Xlib_Display* dpy, Xlib_Window win) {
|
||||
const char* strings[] = {
|
||||
"WM_PROTOCOLS",
|
||||
"ATOM",
|
||||
"WM_DELETE_WINDOW"
|
||||
};
|
||||
Atom atoms[3];
|
||||
int status;
|
||||
status = XInternAtoms(dpy, (char**)(strings), 3, False, atoms);
|
||||
if (status == 0)
|
||||
abortf("XInternAtoms");
|
||||
status = XChangeProperty(dpy, win, atoms[0], atoms[1], 32, PropModeReplace, (unsigned char *)&atoms[2], 1);
|
||||
if (status == 0)
|
||||
abortf("XChangeProperty");
|
||||
}
|
||||
|
||||
// todo: delete this crap
|
||||
typedef struct {
|
||||
Xlib_Atom A_WM_windel;
|
||||
Xlib_Atom A_WM_protocols;
|
||||
int width;
|
||||
int height;
|
||||
bool should_stop;
|
||||
Xlib_Window win;
|
||||
} Margaret_WEP;
|
||||
|
||||
// todo: delete this crap
|
||||
Margaret_WEP Margaret_WEP_new(Xlib_Display* dpy, Xlib_Window win) {
|
||||
return (Margaret_WEP){
|
||||
.A_WM_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False),
|
||||
.A_WM_windel = XInternAtom(dpy, "WM_DELETE_WINDOW", False),
|
||||
.should_stop = false,
|
||||
.win = win,
|
||||
};
|
||||
}
|
||||
|
||||
// todo: delete this crap
|
||||
void Margaret_WEP_update_with_new_event(Margaret_WEP* self, const Xlib_Event* ev) {
|
||||
if (ev->xany.window != self->win)
|
||||
return;
|
||||
if (ev->type == ConfigureNotify) {
|
||||
printf("That was ConfigureNotify\n");
|
||||
self->width = ev->xconfigure.width;
|
||||
self->height = ev->xconfigure.height;
|
||||
} else if (ev->type == ClientMessage) {
|
||||
printf("That was ClientMessage\n");
|
||||
if (ev->xclient.message_type == self->A_WM_protocols &&
|
||||
ev->xclient.format == 32 && ev->xclient.data.l[0] == self->A_WM_windel
|
||||
){
|
||||
printf("WM_DELETE_WINDOW\n");
|
||||
self->should_stop = true;
|
||||
}
|
||||
} else if (ev->type == DestroyNotify) {
|
||||
printf("That was DestroyNotify\n");
|
||||
self->should_stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
void margaret_create_debug_utils_messenger_EXT(
|
||||
VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
|
||||
@ -134,73 +53,6 @@ typedef struct {
|
||||
VkDebugUtilsMessengerEXT debug_messenger;
|
||||
} MargaretInstanceAndItsDebug;
|
||||
|
||||
// todo: delete this crap
|
||||
MargaretInstanceAndItsDebug MargaretInstanceAndItsDebug_new_xlib_flavour(bool enable_validation_layers) {
|
||||
// InstanceAndDebugHands res{};
|
||||
VkApplicationInfo app_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pApplicationName = "Kto prochital tot zdohnet",
|
||||
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||
.pEngineName = "Margaret",
|
||||
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||
.apiVersion = VK_API_VERSION_1_2,
|
||||
};
|
||||
|
||||
VecCSTR needed_extensions = VecCSTR_new();
|
||||
VecCSTR_append(&needed_extensions, "VK_KHR_xlib_surface");
|
||||
VecCSTR_append(&needed_extensions, "VK_KHR_surface");
|
||||
VecCSTR needed_layers = VecCSTR_new();
|
||||
if (enable_validation_layers) {
|
||||
VecCSTR_append(&needed_extensions, "VK_EXT_debug_utils");
|
||||
VecCSTR_append(&needed_layers, "VK_LAYER_KHRONOS_validation");
|
||||
}
|
||||
|
||||
VkInstanceCreateInfo instance_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
// .pNext may be set to `for-instance-creation-only` Debug Messanger crinfo later
|
||||
.pApplicationInfo = &app_info,
|
||||
.enabledLayerCount = needed_layers.len,
|
||||
.ppEnabledLayerNames = needed_layers.buf,
|
||||
.enabledExtensionCount = needed_extensions.len,
|
||||
.ppEnabledExtensionNames = needed_extensions.buf,
|
||||
};
|
||||
|
||||
if (enable_validation_layers) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT debug_messenger_2_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.pfnUserCallback = margaret_static_debug_callback,
|
||||
.pUserData = NULL,
|
||||
};
|
||||
instance_crinfo.pNext = &debug_messenger_2_crinfo;
|
||||
}
|
||||
VkInstance instance;
|
||||
if (vkCreateInstance(&instance_crinfo, NULL, &instance) != VK_SUCCESS)
|
||||
abortf("Failed to create Vulkan instance");
|
||||
VkDebugUtilsMessengerEXT debug_messenger = NULL;
|
||||
if (enable_validation_layers) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT debug_messenger_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.pfnUserCallback = margaret_static_debug_callback,
|
||||
.pUserData = NULL,
|
||||
};
|
||||
margaret_create_debug_utils_messenger_EXT(instance, &debug_messenger_crinfo, NULL, &debug_messenger);
|
||||
}
|
||||
|
||||
return (MargaretInstanceAndItsDebug){.instance = instance, .debug_messenger = debug_messenger};
|
||||
}
|
||||
|
||||
NODISCARD MargaretInstanceAndItsDebug MargaretInstanceAndItsDebug_new(bool enable_validation_layers) {
|
||||
VkApplicationInfo app_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
@ -387,8 +239,10 @@ VkDevice margaret_create_logical_device(VkPhysicalDevice physical_device, Margar
|
||||
return device;
|
||||
}
|
||||
|
||||
#include "../../../gen/l2/eve/OptionVkExtent2D.h"
|
||||
#include "../../../gen/l2/eve/VecAndOption_VkSurfaceFormatKHR.h"
|
||||
#include "../../../gen/l2/eve/VecAndOption_VkPresentModeKHR.h"
|
||||
#include "../../../gen/l2/eve/OptionVkCompositeAlphaFlagBitsKHR.h"
|
||||
|
||||
/* These variables are in some way enforced by VkSurfaceCapabilitiesKHR (but not completely determined) */
|
||||
typedef struct {
|
||||
@ -397,6 +251,7 @@ typedef struct {
|
||||
VkExtent2D image_extent;
|
||||
uint32_t image_count;
|
||||
VkSurfaceTransformFlagBitsKHR surface_pre_transform;
|
||||
VkCompositeAlphaFlagBitsKHR composite_alpha;
|
||||
} MargaretChosenSwapchainDetails;
|
||||
|
||||
OptionVkSurfaceFormatKHR margaret_choose_surface_format(const VecVkSurfaceFormatKHR* surface_formats) {
|
||||
@ -423,11 +278,24 @@ OptionVkPresentModeKHR margaret_choose_presentation_mode(const VecVkPresentModeK
|
||||
return res;
|
||||
}
|
||||
|
||||
VkExtent2D margaret_choose_image_extent(const VkSurfaceCapabilitiesKHR* capabilities) {
|
||||
OptionVkCompositeAlphaFlagBitsKHR margaret_choose_composite_alpha(VkCompositeAlphaFlagBitsKHR bits) {
|
||||
if (bits & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
|
||||
return Some_VkCompositeAlphaFlagBitsKHR(VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR);
|
||||
if (bits & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
|
||||
return Some_VkCompositeAlphaFlagBitsKHR(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
||||
return None_VkCompositeAlphaFlagBitsKHR();
|
||||
}
|
||||
|
||||
OptionVkExtent2D margaret_choose_image_extent(const VkSurfaceCapabilitiesKHR* capabilities, VkExtent2D sane_limits) {
|
||||
if (capabilities->currentExtent.width == UINT32_MAX) {
|
||||
return (VkExtent2D){ capabilities->maxImageExtent.width, capabilities->maxImageExtent.height,};
|
||||
} else
|
||||
return capabilities->currentExtent;
|
||||
if (capabilities->minImageExtent.width > sane_limits.width ||
|
||||
capabilities->minImageExtent.height > sane_limits.height)
|
||||
return None_VkExtent2D();
|
||||
return Some_VkExtent2D ((VkExtent2D) { MIN_U32(sane_limits.width, sane_limits.width),
|
||||
MIN_U32(sane_limits.height, sane_limits.height) });
|
||||
}
|
||||
/* May be bigger, than a sane limit */
|
||||
return capabilities->currentExtent;
|
||||
}
|
||||
|
||||
uint32_t margaret_choose_swapchain_image_count(const VkSurfaceCapabilitiesKHR* capabilities) {
|
||||
@ -478,6 +346,11 @@ ResultMargaretChosenSwapchainDetailsOrSpanU8 margaret_choose_swapchain_details(V
|
||||
VkExtent2D image_extent = margaret_choose_image_extent(&surface_capabilities);
|
||||
uint32_t image_count = margaret_choose_swapchain_image_count(&surface_capabilities);
|
||||
|
||||
OptionVkCompositeAlphaFlagBitsKHR chosen_composite_alpha = margaret_choose_composite_alpha(
|
||||
surface_capabilities.supportedCompositeAlpha);
|
||||
if (chosen_composite_alpha.variant == Option_None)
|
||||
return (ResultMargaretChosenSwapchainDetailsOrSpanU8){.variant = Result_Err, .err = cstr("No composite alpha")};
|
||||
|
||||
VecVkSurfaceFormatKHR_drop(surface_formats);
|
||||
VecVkPresentModeKHR_drop(pres_modes);
|
||||
|
||||
@ -485,7 +358,8 @@ ResultMargaretChosenSwapchainDetailsOrSpanU8 margaret_choose_swapchain_details(V
|
||||
.ok = (MargaretChosenSwapchainDetails){
|
||||
.surface_format = chosen_surface_format.some, .presentation_mode = chosen_present_mode.some,
|
||||
.image_extent = image_extent, .image_count = image_count,
|
||||
.surface_pre_transform = surface_capabilities.currentTransform
|
||||
.surface_pre_transform = surface_capabilities.currentTransform,
|
||||
.composite_alpha = chosen_composite_alpha.some
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -673,7 +547,7 @@ VkSwapchainKHR margaret_create_swapchain (
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
// Filling imageSharingMode and queueFamilyIndexes later
|
||||
.preTransform = swapchain_details.surface_pre_transform,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
|
||||
.compositeAlpha = swapchain_details.composite_alpha,
|
||||
.presentMode = swapchain_details.presentation_mode,
|
||||
.clipped = VK_TRUE,
|
||||
.oldSwapchain = old_swapchain,
|
||||
@ -867,53 +741,6 @@ VkCommandBuffer margaret_allocate_command_buffer(VkDevice device, VkCommandPool
|
||||
return res;
|
||||
}
|
||||
|
||||
// todo: remove this dumb crap
|
||||
typedef struct {
|
||||
Xlib_Display* dpy;
|
||||
Xlib_Window win;
|
||||
} MargaretSingleWindowSetup_XlibFlavour;
|
||||
|
||||
// todo: delte this garbage
|
||||
MargaretSingleWindowSetup_XlibFlavour MargaretSingleWindowSetup_XlibFlavour_new() {
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
if (!dpy)
|
||||
abortf("Unable to open X display");
|
||||
|
||||
int screen = DefaultScreen(dpy);
|
||||
Window root = RootWindow(dpy, screen);
|
||||
|
||||
unsigned long black = BlackPixel(dpy, screen);
|
||||
unsigned long white = WhitePixel(dpy, screen);
|
||||
int win_x = 50, win_y = 50;
|
||||
unsigned int win_w = 400, win_h = 300;
|
||||
Window win = XCreateSimpleWindow(
|
||||
dpy, root,
|
||||
win_x, win_y, win_w, win_h,
|
||||
1, black, white
|
||||
);
|
||||
margaret_win_init_set_properties(dpy, win);
|
||||
|
||||
/* 3) Select for ConfigureNotify and Expose events */
|
||||
XSelectInput(dpy, win, StructureNotifyMask | ExposureMask | PointerMotionMask | KeyPressMask | KeyReleaseMask);
|
||||
return (MargaretSingleWindowSetup_XlibFlavour){ .dpy = dpy, .win = win };
|
||||
}
|
||||
|
||||
// todo: ahfadlhja kjdelete this crap
|
||||
void MargaretSingleWindowSetup_XlibFlavour_drop(MargaretSingleWindowSetup_XlibFlavour x) {
|
||||
XDestroyWindow(x.dpy, x.win);
|
||||
XCloseDisplay(x.dpy);
|
||||
}
|
||||
|
||||
// todo: delete this crap. We are gonna use libwayland
|
||||
VkSurfaceKHR margaret_create_surface_x_dunk(VkInstance instance, const MargaretSingleWindowSetup_XlibFlavour* x) {
|
||||
VkXlibSurfaceCreateInfoKHR surface_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .dpy = x->dpy, .window = x->win,
|
||||
};
|
||||
VkSurfaceKHR surface;
|
||||
if (vkCreateXlibSurfaceKHR(instance, &surface_crinfo, NULL, &surface) != VK_SUCCESS)
|
||||
abortf("Failed to create Vulkan surface");
|
||||
return surface;
|
||||
}
|
||||
|
||||
VkSurfaceKHR margaret_create_surface(VkInstance instance, struct wl_display* wl_display, struct wl_surface* wl_surface) {
|
||||
VkWaylandSurfaceCreateInfoKHR crinfo = {
|
||||
|
||||
@ -6,6 +6,207 @@
|
||||
#include "r0_scene.h"
|
||||
#include <sys/wait.h> // Only for linux
|
||||
|
||||
/* I temporarily moved all the Xlib crap here, away from margaret. todo: remove crap from here too */
|
||||
// todo: rewrite this crap to wayland (fom now on wayland is my best friend in all situations)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
// todo: rewrite margaret to use libwayland-client, and get rid of this fucking crap
|
||||
typedef XEvent Xlib_Event;
|
||||
|
||||
#include "../../../../gen/l2/eve/VecXlib_Event.h"
|
||||
|
||||
// todo: AAAAAAAAAAAAA I HATE XLIB SO FUCKINGG MNJUHC AAAASAAAAA AAAAAAA
|
||||
typedef Display Xlib_Display;
|
||||
typedef Window Xlib_Window;
|
||||
typedef Atom Xlib_Atom;
|
||||
|
||||
// todo: AAAAAAAAAAAAAAAA AAASASDASDASDASDAGAHGFKJG AAAAAAAAAAA FUCK XLIB FUCK XORG FUCK THIS SHIT
|
||||
NODISCARD VecXlib_Event margaret_read_x_events(Xlib_Display* dpy) {
|
||||
int evh = XEventsQueued(dpy, QueuedAfterReading);
|
||||
VecXlib_Event result = VecXlib_Event_new_zeroinit(evh);
|
||||
for (int i = 0; i < evh; i++) {
|
||||
XNextEvent(dpy, VecXlib_Event_mat(&result, i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void margaret_win_init_set_properties(Xlib_Display* dpy, Xlib_Window win) {
|
||||
const char* strings[] = {
|
||||
"WM_PROTOCOLS",
|
||||
"ATOM",
|
||||
"WM_DELETE_WINDOW"
|
||||
};
|
||||
Atom atoms[3];
|
||||
int status;
|
||||
status = XInternAtoms(dpy, (char**)(strings), 3, False, atoms);
|
||||
if (status == 0)
|
||||
abortf("XInternAtoms");
|
||||
status = XChangeProperty(dpy, win, atoms[0], atoms[1], 32, PropModeReplace, (unsigned char *)&atoms[2], 1);
|
||||
if (status == 0)
|
||||
abortf("XChangeProperty");
|
||||
}
|
||||
|
||||
// todo: delete this crap
|
||||
typedef struct {
|
||||
Xlib_Atom A_WM_windel;
|
||||
Xlib_Atom A_WM_protocols;
|
||||
int width;
|
||||
int height;
|
||||
bool should_stop;
|
||||
Xlib_Window win;
|
||||
} Margaret_WEP;
|
||||
|
||||
// todo: delete this crap
|
||||
Margaret_WEP Margaret_WEP_new(Xlib_Display* dpy, Xlib_Window win) {
|
||||
return (Margaret_WEP){
|
||||
.A_WM_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False),
|
||||
.A_WM_windel = XInternAtom(dpy, "WM_DELETE_WINDOW", False),
|
||||
.should_stop = false,
|
||||
.win = win,
|
||||
};
|
||||
}
|
||||
|
||||
// todo: delete this crap
|
||||
void Margaret_WEP_update_with_new_event(Margaret_WEP* self, const Xlib_Event* ev) {
|
||||
if (ev->xany.window != self->win)
|
||||
return;
|
||||
if (ev->type == ConfigureNotify) {
|
||||
printf("That was ConfigureNotify\n");
|
||||
self->width = ev->xconfigure.width;
|
||||
self->height = ev->xconfigure.height;
|
||||
} else if (ev->type == ClientMessage) {
|
||||
printf("That was ClientMessage\n");
|
||||
if (ev->xclient.message_type == self->A_WM_protocols &&
|
||||
ev->xclient.format == 32 && ev->xclient.data.l[0] == self->A_WM_windel
|
||||
){
|
||||
printf("WM_DELETE_WINDOW\n");
|
||||
self->should_stop = true;
|
||||
}
|
||||
} else if (ev->type == DestroyNotify) {
|
||||
printf("That was DestroyNotify\n");
|
||||
self->should_stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// todo: delete this crap
|
||||
MargaretInstanceAndItsDebug MargaretInstanceAndItsDebug_new_xlib_flavour(bool enable_validation_layers) {
|
||||
// InstanceAndDebugHands res{};
|
||||
VkApplicationInfo app_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pApplicationName = "Kto prochital tot zdohnet",
|
||||
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||
.pEngineName = "Margaret",
|
||||
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||
.apiVersion = VK_API_VERSION_1_2,
|
||||
};
|
||||
|
||||
VecCSTR needed_extensions = VecCSTR_new();
|
||||
VecCSTR_append(&needed_extensions, "VK_KHR_xlib_surface");
|
||||
VecCSTR_append(&needed_extensions, "VK_KHR_surface");
|
||||
VecCSTR needed_layers = VecCSTR_new();
|
||||
if (enable_validation_layers) {
|
||||
VecCSTR_append(&needed_extensions, "VK_EXT_debug_utils");
|
||||
VecCSTR_append(&needed_layers, "VK_LAYER_KHRONOS_validation");
|
||||
}
|
||||
|
||||
VkInstanceCreateInfo instance_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
// .pNext may be set to `for-instance-creation-only` Debug Messanger crinfo later
|
||||
.pApplicationInfo = &app_info,
|
||||
.enabledLayerCount = needed_layers.len,
|
||||
.ppEnabledLayerNames = needed_layers.buf,
|
||||
.enabledExtensionCount = needed_extensions.len,
|
||||
.ppEnabledExtensionNames = needed_extensions.buf,
|
||||
};
|
||||
|
||||
if (enable_validation_layers) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT debug_messenger_2_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.pfnUserCallback = margaret_static_debug_callback,
|
||||
.pUserData = NULL,
|
||||
};
|
||||
instance_crinfo.pNext = &debug_messenger_2_crinfo;
|
||||
}
|
||||
VkInstance instance;
|
||||
if (vkCreateInstance(&instance_crinfo, NULL, &instance) != VK_SUCCESS)
|
||||
abortf("Failed to create Vulkan instance");
|
||||
VkDebugUtilsMessengerEXT debug_messenger = NULL;
|
||||
if (enable_validation_layers) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT debug_messenger_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.pfnUserCallback = margaret_static_debug_callback,
|
||||
.pUserData = NULL,
|
||||
};
|
||||
margaret_create_debug_utils_messenger_EXT(instance, &debug_messenger_crinfo, NULL, &debug_messenger);
|
||||
}
|
||||
|
||||
return (MargaretInstanceAndItsDebug){.instance = instance, .debug_messenger = debug_messenger};
|
||||
}
|
||||
|
||||
// todo: remove this dumb crap
|
||||
typedef struct {
|
||||
Xlib_Display* dpy;
|
||||
Xlib_Window win;
|
||||
} MargaretSingleWindowSetup_XlibFlavour;
|
||||
|
||||
// todo: delte this garbage
|
||||
MargaretSingleWindowSetup_XlibFlavour MargaretSingleWindowSetup_XlibFlavour_new() {
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
if (!dpy)
|
||||
abortf("Unable to open X display");
|
||||
|
||||
int screen = DefaultScreen(dpy);
|
||||
Window root = RootWindow(dpy, screen);
|
||||
|
||||
unsigned long black = BlackPixel(dpy, screen);
|
||||
unsigned long white = WhitePixel(dpy, screen);
|
||||
int win_x = 50, win_y = 50;
|
||||
unsigned int win_w = 400, win_h = 300;
|
||||
Window win = XCreateSimpleWindow(
|
||||
dpy, root,
|
||||
win_x, win_y, win_w, win_h,
|
||||
1, black, white
|
||||
);
|
||||
margaret_win_init_set_properties(dpy, win);
|
||||
|
||||
/* 3) Select for ConfigureNotify and Expose events */
|
||||
XSelectInput(dpy, win, StructureNotifyMask | ExposureMask | PointerMotionMask | KeyPressMask | KeyReleaseMask);
|
||||
return (MargaretSingleWindowSetup_XlibFlavour){ .dpy = dpy, .win = win };
|
||||
}
|
||||
|
||||
// todo: ahfadlhja kjdelete this crap
|
||||
void MargaretSingleWindowSetup_XlibFlavour_drop(MargaretSingleWindowSetup_XlibFlavour x) {
|
||||
XDestroyWindow(x.dpy, x.win);
|
||||
XCloseDisplay(x.dpy);
|
||||
}
|
||||
|
||||
// todo: delete this crap. We are gonna use libwayland
|
||||
VkSurfaceKHR margaret_create_surface_x_dunk(VkInstance instance, const MargaretSingleWindowSetup_XlibFlavour* x) {
|
||||
VkXlibSurfaceCreateInfoKHR surface_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .dpy = x->dpy, .window = x->win,
|
||||
};
|
||||
VkSurfaceKHR surface;
|
||||
if (vkCreateXlibSurfaceKHR(instance, &surface_crinfo, NULL, &surface) != VK_SUCCESS)
|
||||
abortf("Failed to create Vulkan surface");
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// todo: generate this class in l2
|
||||
typedef struct {
|
||||
VkPipelineLayout pipeline_layout;
|
||||
|
||||
@ -80,7 +80,7 @@ void reset_and_record_command_buffer_0(
|
||||
if (vkBeginCommandBuffer(command_buffer, &info_begin) != VK_SUCCESS)
|
||||
abortf("vkBeginCommandBuffer");
|
||||
|
||||
VkClearValue clear_values[1] = {{.color = {.float32={0, fabsf(sinf(ht)), 0, 1}}},};
|
||||
VkClearValue clear_values[1] = {{.color = {.float32={1, fabsf(sinf(ht)), 0, 1}}},};
|
||||
VkRenderPassBeginInfo renderpass_begin = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = render_pass_0,
|
||||
@ -138,7 +138,11 @@ typedef struct {
|
||||
VkSurfaceKHR vk_surface;
|
||||
VkQueue graphics_queue;
|
||||
VkQueue presentation_queue;
|
||||
VkRenderPass render_pass_0;
|
||||
MargaretSwapchainBundle swfb;
|
||||
VkCommandPool command_pool;
|
||||
VkCommandBuffer rendering_command_buffer_0;
|
||||
Jane_r3 jane;
|
||||
/* inputs */
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_keyboard* keyboard;
|
||||
@ -153,6 +157,9 @@ typedef struct {
|
||||
int32_t height;
|
||||
bool closed;
|
||||
bool first_0x80_keys[0x80];
|
||||
/* framerate counting */
|
||||
U32 frame_count_since_key;
|
||||
margaret_ns_time prev_key_frame_time;
|
||||
} state_t;
|
||||
|
||||
void draw_frame(state_t* state, uint32_t* data, int32_t width, int32_t height) {
|
||||
@ -403,30 +410,135 @@ static const struct wl_registry_listener main_h_wl_registry_listener = {
|
||||
.global_remove = main_h_wl_registry_global_remove,
|
||||
};
|
||||
|
||||
// static const struct wl_callback_listener main_h_wl_surface_frame_listener;
|
||||
//
|
||||
// static void main_h_wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time){
|
||||
// state_t *state = data;
|
||||
// wl_callback_destroy(cb);
|
||||
// // todo: when I add multiple surfaces, gonna need to think of something smarter
|
||||
// state->wl_callback = wl_surface_frame(state->wl_surface);
|
||||
// if (!state->wl_callback)
|
||||
// abortf("wl_surface_frame\n");
|
||||
// wl_callback_add_listener(state->wl_callback, &main_h_wl_surface_frame_listener, state);
|
||||
//
|
||||
// if (state->last_frame_time != 0) {
|
||||
// update_state(state, time - state->last_frame_time);
|
||||
// }
|
||||
//
|
||||
// state->swapchain.want_to_draw = true;
|
||||
// try_drawing_frame(state);
|
||||
//
|
||||
// state->last_frame_time = time;
|
||||
// }
|
||||
//
|
||||
// static const struct wl_callback_listener main_h_wl_surface_frame_listener = {
|
||||
// .done = main_h_wl_surface_frame_done,
|
||||
// };
|
||||
static const struct wl_callback_listener main_h_wl_surface_frame_listener;
|
||||
|
||||
void recreate_swapchain(state_t* state) {
|
||||
// We are about stop program and rebuild our sem+sem+fence synchronization mechanism
|
||||
vkDeviceWaitIdle(state->device);
|
||||
Jane_r3_destroy(state->device, state->jane);
|
||||
state->jane = Jane_r3_create(state->device);
|
||||
VkSwapchainKHR old_swapchain = MargaretSwapchainBundle_pop_swapchain_drop_rest(state->device, state->swfb);
|
||||
// old swfb is 83% dropped
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(
|
||||
state->physical_device, state->vk_surface);
|
||||
if (swapchain_details_res.variant != Result_Ok)
|
||||
abortf("swapchain_details_res.variant != Result_Ok");
|
||||
MargaretChosenSwapchainDetails swapchain_details = swapchain_details_res.ok;
|
||||
MargaretSwapchainBundle new_swfb = MargaretSwapchainBundle_new(
|
||||
state->device, state->queue_fam, swapchain_details, state->vk_surface,
|
||||
state->render_pass_0, state->swfb.swapchain);
|
||||
vkDestroySwapchainKHR(state->device, old_swapchain, NULL);
|
||||
// Now old swfb is 100% dropped
|
||||
state->swfb = new_swfb;
|
||||
}
|
||||
|
||||
|
||||
void vulkano_frame_drawing(state_t* state) {
|
||||
// Rendering
|
||||
and_try_again:
|
||||
vkWaitForFences(state->device, 1, &state->jane.in_flight_fence, VK_TRUE, UINT64_MAX);
|
||||
uint32_t ij;
|
||||
VkResult aq_ret = vkAcquireNextImageKHR(
|
||||
state->device, state->swfb.swapchain,
|
||||
UINT64_MAX, state->jane.image_available_semaphore, VK_NULL_HANDLE, &ij
|
||||
);
|
||||
if (aq_ret == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
fprintf(stderr, "vkAcquireNextImageKHR: VK_ERROR_OUT_OF_DATE_KHR\n");
|
||||
recreate_swapchain(state);
|
||||
goto and_try_again;
|
||||
} else if (aq_ret == VK_SUBOPTIMAL_KHR) {
|
||||
fprintf(stderr, "vkAcquireNextImageKHR: VK_SUBOPTIMAL_KHR\n");
|
||||
recreate_swapchain(state);
|
||||
goto and_try_again;
|
||||
} else if (aq_ret != VK_SUCCESS) {
|
||||
abortf("vkAcquireNextImageKHR");
|
||||
}
|
||||
|
||||
vkResetFences(state->device, 1, &state->jane.in_flight_fence);
|
||||
|
||||
reset_and_record_command_buffer_0(state->rendering_command_buffer_0, state->render_pass_0,
|
||||
*VecVkFramebuffer_at(&state->swfb.framebuffers, ij), state->swfb.extent, state->ht);
|
||||
|
||||
{
|
||||
VkCommandBuffer command_buffers[1] = {state->rendering_command_buffer_0};
|
||||
VkSemaphore signaling_semaphores[1] = { state->jane.render_finished_semaphore };
|
||||
VkSubmitInfo submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
|
||||
.waitSemaphoreCount = 0,
|
||||
.pWaitSemaphores = NULL,
|
||||
.pWaitDstStageMask = NULL,
|
||||
|
||||
.commandBufferCount = ARRAY_SIZE(command_buffers),
|
||||
.pCommandBuffers = command_buffers,
|
||||
|
||||
.signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
|
||||
.pSignalSemaphores = signaling_semaphores,
|
||||
};
|
||||
if (vkQueueSubmit(state->graphics_queue, 1, &submit_info, NULL) != VK_SUCCESS)
|
||||
abortf("vkQueueSubmit");
|
||||
}
|
||||
|
||||
{
|
||||
VkSemaphore waiting_for_semaphores[] = { state->jane.render_finished_semaphore };
|
||||
VkSwapchainKHR swapchains[] = { state->swfb.swapchain };
|
||||
uint32_t image_indices[] = { ij };
|
||||
assert( ARRAY_SIZE(swapchains) == ARRAY_SIZE(image_indices) );
|
||||
|
||||
VkPresentInfoKHR present_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.waitSemaphoreCount = ARRAY_SIZE(waiting_for_semaphores),
|
||||
.pWaitSemaphores = waiting_for_semaphores,
|
||||
|
||||
.swapchainCount = ARRAY_SIZE(swapchains),
|
||||
.pSwapchains = swapchains,
|
||||
.pImageIndices = image_indices,
|
||||
.pResults = NULL,
|
||||
};
|
||||
|
||||
VkResult pres_ret = vkQueuePresentKHR(state->presentation_queue, &present_info);
|
||||
// todo: ponder more over this
|
||||
if (pres_ret == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
fprintf(stderr, "vkQueuePresentKHR: VK_ERROR_OUT_OF_DATE_KHR\n");
|
||||
recreate_swapchain(state);
|
||||
goto and_try_again;
|
||||
} else if (pres_ret == VK_SUBOPTIMAL_KHR) {
|
||||
fprintf(stderr, "vkQueuePresentKHR: VK_SUBOPTIMAL_KHR\n");
|
||||
recreate_swapchain(state);
|
||||
goto and_try_again;
|
||||
} else if (pres_ret != VK_SUCCESS) {
|
||||
abortf("vkQueuePresentKHR");
|
||||
}
|
||||
}
|
||||
margaret_ns_time frame_B0 = margaret_clock_gettime_monotonic_raw();
|
||||
state->frame_count_since_key++;
|
||||
if (margaret_ns_time_sec_diff(state->prev_key_frame_time, frame_B0) > 1.0) {
|
||||
float fps = (float)state->frame_count_since_key / margaret_ns_time_sec_diff(state->prev_key_frame_time, frame_B0);
|
||||
printf("FPS: %0.1f\n", fps);
|
||||
state->frame_count_since_key = 0;
|
||||
state->prev_key_frame_time = frame_B0;
|
||||
}
|
||||
}
|
||||
|
||||
static void main_h_wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time){
|
||||
state_t *state = data;
|
||||
wl_callback_destroy(cb);
|
||||
// todo: when I add multiple surfaces, gonna need to think of something smarter
|
||||
state->wl_callback = wl_surface_frame(state->wl_surface);
|
||||
if (!state->wl_callback)
|
||||
abortf("wl_surface_frame\n");
|
||||
wl_callback_add_listener(state->wl_callback, &main_h_wl_surface_frame_listener, state);
|
||||
|
||||
if (state->last_frame_time != 0) {
|
||||
update_state(state, time - state->last_frame_time);
|
||||
}
|
||||
vulkano_frame_drawing(state);
|
||||
state->last_frame_time = time;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener main_h_wl_surface_frame_listener = {
|
||||
.done = main_h_wl_surface_frame_done,
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
@ -481,28 +593,33 @@ int main() {
|
||||
vkGetDeviceQueue(state.device, state.queue_fam.for_graphics, 0, &state.graphics_queue);
|
||||
VkQueue presentation_queue;
|
||||
vkGetDeviceQueue(state.device, state.queue_fam.for_presentation, 0, &presentation_queue);
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(physical_device, vk_surface);
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(
|
||||
state.physical_device, state.vk_surface);
|
||||
if (swapchain_details_res.variant != Result_Ok)
|
||||
abortf("swapchain_details_res.variant != Result_Ok");
|
||||
MargaretChosenSwapchainDetails swapchain_details = swapchain_details_res.ok;
|
||||
VkRenderPass render_pass_0 = create_render_pass_0(device, swapchain_details.surface_format.format);
|
||||
state.render_pass_0 = create_render_pass_0(state.device, swapchain_details.surface_format.format);
|
||||
// PipelineHands pipeline_hands_0 = create_graphics_pipeline_0(device, render_pass_0, 0);
|
||||
|
||||
MargaretSwapchainBundle swfb = MargaretSwapchainBundle_new(device, queue_fam, swapchain_details_res.ok, vk_surface, render_pass_0, NULL);
|
||||
VkCommandPool command_pool = margaret_create_resettable_command_pool(device, queue_fam.for_graphics);
|
||||
VkCommandBuffer rendering_command_buffer_0 = margaret_allocate_command_buffer(device, command_pool);
|
||||
state.swfb = MargaretSwapchainBundle_new(state.device, state.queue_fam,
|
||||
swapchain_details_res.ok, state.vk_surface, state.render_pass_0, NULL);
|
||||
state.command_pool = margaret_create_resettable_command_pool(state.device, state.queue_fam.for_graphics);
|
||||
state.rendering_command_buffer_0 = margaret_allocate_command_buffer(state.device, state.command_pool);
|
||||
|
||||
Jane_r3 jane = Jane_r3_create(device);
|
||||
state.jane = Jane_r3_create(state.device);
|
||||
|
||||
// todo: write what I need to write
|
||||
int wl_display_loop_fd = wl_display_get_fd(state.wl_display);
|
||||
struct pollfd mainloop_fds[1] = {(struct pollfd){}};
|
||||
// int wl_display_loop_fd = wl_display_get_fd(state.wl_display);
|
||||
// struct pollfd mainloop_fds[1] = {(struct pollfd){}};
|
||||
while (wl_display_dispatch(state.wl_display)) {
|
||||
if (state.closed)
|
||||
break;
|
||||
}
|
||||
// if (state.wl_callback)
|
||||
// wl_callback_destroy(state.wl_callback);
|
||||
vkDeviceWaitIdle(state.device);
|
||||
// todo: destroy instance and all the shit
|
||||
|
||||
|
||||
if (state.wl_callback)
|
||||
wl_callback_destroy(state.wl_callback);
|
||||
xdg_toplevel_destroy(state.xdg_toplevel);
|
||||
xdg_surface_destroy(state.xdg_surface);
|
||||
xdg_wm_base_destroy(state.xdg_wm_base);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user