Compare commits
2 Commits
fc7884a9ed
...
d4d97ed8c6
| Author | SHA1 | Date | |
|---|---|---|---|
| d4d97ed8c6 | |||
| 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(%s obj) {\n"
|
||||
SPACE4 "return (%s){ .variant = Option_Some, .some = obj };\n"
|
||||
"}\n\n", OptionT, T, 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"),
|
||||
@ -44,6 +48,7 @@ void eve_of_l2() {
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkImage"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkImageView"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkFramebuffer"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkSemaphore"), true, false);
|
||||
generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("MargaretBufferInMemoryInfo"), true, false);
|
||||
generate_eve_header(cstr("l2"), cstr(""), cstr("PtrMargaretBufferInMemoryInfo"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
|
||||
@ -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 Some_VkExtent2D(capabilities->currentExtent);
|
||||
}
|
||||
|
||||
uint32_t margaret_choose_swapchain_image_count(const VkSurfaceCapabilitiesKHR* capabilities) {
|
||||
@ -445,7 +313,9 @@ typedef struct {
|
||||
} ResultMargaretChosenSwapchainDetailsOrSpanU8;
|
||||
|
||||
// Both queries swapchain support details and selects needed formats and presentation modes
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 margaret_choose_swapchain_details(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 margaret_choose_swapchain_details(
|
||||
VkPhysicalDevice physical_device, VkSurfaceKHR surface, VkExtent2D sane_image_extent_limit
|
||||
) {
|
||||
/* 1. Getting surface capabilities + formats + presentation modes */
|
||||
VkSurfaceCapabilitiesKHR surface_capabilities;
|
||||
if (vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_capabilities) != VK_SUCCESS)
|
||||
@ -475,17 +345,27 @@ ResultMargaretChosenSwapchainDetailsOrSpanU8 margaret_choose_swapchain_details(V
|
||||
return (ResultMargaretChosenSwapchainDetailsOrSpanU8){ .variant = Result_Err,
|
||||
.err = cstr("No suitable swapchain presentation mode") };
|
||||
|
||||
VkExtent2D image_extent = margaret_choose_image_extent(&surface_capabilities);
|
||||
OptionVkExtent2D image_extent = margaret_choose_image_extent(&surface_capabilities, sane_image_extent_limit);
|
||||
if (image_extent.variant == Option_None)
|
||||
return (ResultMargaretChosenSwapchainDetailsOrSpanU8){ .variant = Result_Err,
|
||||
.err = cstr("Can't choose sane image extent")};
|
||||
|
||||
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);
|
||||
|
||||
return (ResultMargaretChosenSwapchainDetailsOrSpanU8){ .variant = Result_Ok,\
|
||||
.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
|
||||
.image_extent = image_extent.some, .image_count = image_count,
|
||||
.surface_pre_transform = surface_capabilities.currentTransform,
|
||||
.composite_alpha = chosen_composite_alpha.some
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -547,7 +427,8 @@ typedef struct {
|
||||
} MargaretScoredPhysicalDevice;
|
||||
|
||||
MargaretScoredPhysicalDevice margaret_score_physical_device(
|
||||
VkPhysicalDevice dev, VkSurfaceKHR surface, SpanU8 favourite_word, SpanU8 forbidden_word
|
||||
VkPhysicalDevice dev, VkSurfaceKHR surface, SpanU8 favourite_word, SpanU8 forbidden_word,
|
||||
VkExtent2D sane_image_extent_limit
|
||||
) {
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(dev, &properties);
|
||||
@ -589,7 +470,7 @@ MargaretScoredPhysicalDevice margaret_score_physical_device(
|
||||
}
|
||||
VecVecU8_drop(dev_extensions);
|
||||
// Extension VK_KHR_swapchain is present, now we can call query_swap_chain_support
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details = margaret_choose_swapchain_details(dev, surface);
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details = margaret_choose_swapchain_details(dev, surface, sane_image_extent_limit);
|
||||
if (swapchain_details.variant == Result_Err) {
|
||||
return (MargaretScoredPhysicalDevice){dev, -1, cstr("Physical device lacks nice swapchain support")};
|
||||
}
|
||||
@ -611,7 +492,7 @@ MargaretScoredPhysicalDevice margaret_score_physical_device(
|
||||
|
||||
VecMargaretScoredPhysicalDevice margaret_get_physical_devices_scored(
|
||||
VkInstance instance, VkSurfaceKHR surface,
|
||||
SpanU8 favourite_word, SpanU8 forbidden_word
|
||||
SpanU8 favourite_word, SpanU8 forbidden_word, VkExtent2D sane_image_extent_limit
|
||||
) {
|
||||
uint32_t physical_device_count = 0;
|
||||
if (vkEnumeratePhysicalDevices(instance, &physical_device_count, NULL) != VK_SUCCESS)
|
||||
@ -622,7 +503,8 @@ VecMargaretScoredPhysicalDevice margaret_get_physical_devices_scored(
|
||||
VecMargaretScoredPhysicalDevice scored_devices = VecMargaretScoredPhysicalDevice_new_zeroinit(physical_device_count);
|
||||
for (uint32_t i = 0; i < physical_device_count; i++) {
|
||||
*VecMargaretScoredPhysicalDevice_mat(&scored_devices, i) = margaret_score_physical_device(
|
||||
*VecVkPhysicalDevice_at(&physical_devices, i), surface, favourite_word, forbidden_word
|
||||
*VecVkPhysicalDevice_at(&physical_devices, i), surface,
|
||||
favourite_word, forbidden_word, sane_image_extent_limit
|
||||
);
|
||||
}
|
||||
MutSpanMargaretScoredPhysicalDevice_sort(VecMargaretScoredPhysicalDevice_to_mspan(&scored_devices));
|
||||
@ -631,9 +513,10 @@ VecMargaretScoredPhysicalDevice margaret_get_physical_devices_scored(
|
||||
|
||||
VkPhysicalDevice margaret_select_one_physical_device(
|
||||
VkInstance instance, VkSurfaceKHR surface,
|
||||
SpanU8 favourite_word, SpanU8 forbidden_word
|
||||
SpanU8 favourite_word, SpanU8 forbidden_word, VkExtent2D sane_image_extent_limit
|
||||
) {
|
||||
VecMargaretScoredPhysicalDevice scored_devices = margaret_get_physical_devices_scored(instance, surface, favourite_word, forbidden_word);
|
||||
VecMargaretScoredPhysicalDevice scored_devices = margaret_get_physical_devices_scored(instance, surface,
|
||||
favourite_word, forbidden_word, sane_image_extent_limit);
|
||||
printf("Physical devices (with scores):\n");
|
||||
for (size_t i = 0; i < scored_devices.len; i++) {
|
||||
const MargaretScoredPhysicalDevice* dev = VecMargaretScoredPhysicalDevice_at(&scored_devices, i);
|
||||
@ -673,7 +556,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,
|
||||
@ -697,6 +580,7 @@ VkSwapchainKHR margaret_create_swapchain (
|
||||
#include "../../../gen/l2/eve/VecVkImage.h"
|
||||
#include "../../../gen/l2/eve/VecVkImageView.h"
|
||||
#include "../../../gen/l2/eve/VecVkFramebuffer.h"
|
||||
#include "../../../gen/l2/eve/VecVkSemaphore.h"
|
||||
|
||||
VecVkImageView margaret_create_swapchain_image_views(
|
||||
VkDevice device, VkSwapchainKHR swapchain,
|
||||
@ -779,6 +663,7 @@ typedef struct {
|
||||
VecVkImageView image_views;
|
||||
VecVkFramebuffer framebuffers;
|
||||
VkExtent2D extent;
|
||||
VecVkSemaphore rendering_finished_here_semaphores;
|
||||
} MargaretSwapchainBundle;
|
||||
|
||||
MargaretSwapchainBundle MargaretSwapchainBundle_new(
|
||||
@ -788,12 +673,18 @@ MargaretSwapchainBundle MargaretSwapchainBundle_new(
|
||||
VkSwapchainKHR swapchain = margaret_create_swapchain(device, queue_families, swapchain_details, surface, old_swapchain);
|
||||
VecVkImageView image_views = margaret_create_swapchain_image_views(device, swapchain, swapchain_details.surface_format.format);
|
||||
VecVkFramebuffer framebuffers = margaret_create_swapchain_framebuffers(device, &image_views, render_pass, swapchain_details.image_extent);
|
||||
VecVkSemaphore rendering_finished_semaphores = VecVkSemaphore_new_zeroinit(framebuffers.len);
|
||||
for (size_t i = 0; i < framebuffers.len; i++)
|
||||
*VecVkSemaphore_mat(&rendering_finished_semaphores, i) = margaret_create_semaphore(device);
|
||||
return (MargaretSwapchainBundle){ .swapchain = swapchain, .image_views = image_views,
|
||||
.framebuffers = framebuffers, .extent = swapchain_details.image_extent,
|
||||
.rendering_finished_here_semaphores = rendering_finished_semaphores
|
||||
};
|
||||
}
|
||||
|
||||
VkSwapchainKHR MargaretSwapchainBundle_pop_swapchain_drop_rest(VkDevice device, MargaretSwapchainBundle swfb) {
|
||||
for (size_t i = 0; i < swfb.rendering_finished_here_semaphores.len; i++)
|
||||
vkDestroySemaphore(device, *VecVkSemaphore_at(&swfb.rendering_finished_here_semaphores, i), NULL);
|
||||
for (size_t i = 0; i < swfb.framebuffers.len; i++) {
|
||||
vkDestroyFramebuffer(device, *VecVkFramebuffer_at(&swfb.framebuffers, i), NULL);
|
||||
}
|
||||
@ -867,53 +758,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;
|
||||
@ -735,23 +936,20 @@ typedef struct {
|
||||
VkSemaphore in_frame_transfer_complete;
|
||||
VkSemaphore image_available_semaphore;
|
||||
VkSemaphore rendered_to_IT1_semaphore;
|
||||
VkSemaphore render_finished_semaphore;
|
||||
VkFence in_flight_fence;
|
||||
} Jane;
|
||||
} Jane_r0;
|
||||
|
||||
NODISCARD Jane Jane_create(VkDevice device) {
|
||||
return (Jane){
|
||||
NODISCARD Jane_r0 Jane_r0_create(VkDevice device) {
|
||||
return (Jane_r0){
|
||||
.in_frame_transfer_complete = margaret_create_semaphore(device),
|
||||
.image_available_semaphore = margaret_create_semaphore(device),
|
||||
.rendered_to_IT1_semaphore = margaret_create_semaphore(device),
|
||||
.render_finished_semaphore = margaret_create_semaphore(device),
|
||||
.in_flight_fence = margaret_create_fence(device, true)
|
||||
};
|
||||
}
|
||||
|
||||
void Jane_destroy(VkDevice device, Jane jane) {
|
||||
void Jane_r0_destroy(VkDevice device, Jane_r0 jane) {
|
||||
vkDestroyFence(device, jane.in_flight_fence, NULL);
|
||||
vkDestroySemaphore(device, jane.render_finished_semaphore, NULL);
|
||||
vkDestroySemaphore(device, jane.rendered_to_IT1_semaphore, NULL);
|
||||
vkDestroySemaphore(device, jane.image_available_semaphore, NULL);
|
||||
vkDestroySemaphore(device, jane.in_frame_transfer_complete, NULL);
|
||||
@ -759,14 +957,15 @@ void Jane_destroy(VkDevice device, Jane jane) {
|
||||
|
||||
void recreate_swapchain(
|
||||
VkPhysicalDevice physical_device, VkDevice device, MargaretChosenQueueFamilies queue_fam, VkSurfaceKHR surface,
|
||||
VkRenderPass render_pass, MargaretSwapchainBundle* swfb, Jane* jane) {
|
||||
VkRenderPass render_pass, MargaretSwapchainBundle* swfb, Jane_r0* jane, VkExtent2D sane_image_extent_limit) {
|
||||
// We are about stop program and rebuild our sem+sem+fence synchronization mechanism
|
||||
vkDeviceWaitIdle(device);
|
||||
Jane_destroy(device, *jane);
|
||||
*jane = Jane_create(device);
|
||||
Jane_r0_destroy(device, *jane);
|
||||
*jane = Jane_r0_create(device);
|
||||
VkSwapchainKHR old_swapchain = MargaretSwapchainBundle_pop_swapchain_drop_rest(device, *swfb);
|
||||
// old swfb is 83% dropped
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(physical_device, surface);
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(
|
||||
physical_device, surface, sane_image_extent_limit);
|
||||
if (swapchain_details_res.variant != Result_Ok)
|
||||
abortf("swapchain_details_res.variant != Result_Ok");
|
||||
MargaretChosenSwapchainDetails swapchain_details = swapchain_details_res.ok;
|
||||
@ -801,6 +1000,7 @@ int main() {
|
||||
bool ENABLE_VALIDATION_LAYERS = true;
|
||||
const U32 MAX_WIN_WIDTH = 1920;
|
||||
const U32 MAX_WIN_HEIGHT = 1080;
|
||||
VkExtent2D sane_image_extent_limit = {MAX_WIN_WIDTH, MAX_WIN_HEIGHT};
|
||||
|
||||
MargaretSingleWindowSetup_XlibFlavour x = MargaretSingleWindowSetup_XlibFlavour_new();
|
||||
Margaret_WEP wep = Margaret_WEP_new(x.dpy, x.win);
|
||||
@ -814,7 +1014,8 @@ int main() {
|
||||
|
||||
VkSurfaceKHR surface = margaret_create_surface_x_dunk(instance, &x);
|
||||
|
||||
VkPhysicalDevice physical_device = margaret_select_one_physical_device(instance, surface, GPU, bugged_GPU);
|
||||
VkPhysicalDevice physical_device = margaret_select_one_physical_device(
|
||||
instance, surface, GPU, bugged_GPU, sane_image_extent_limit);
|
||||
|
||||
// print_physical_device_available_extensions(physical_device);
|
||||
|
||||
@ -830,7 +1031,8 @@ int main() {
|
||||
VkQueue presentation_queue;
|
||||
vkGetDeviceQueue(device, queue_fam.for_presentation, 0, &presentation_queue);
|
||||
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(physical_device, surface);
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(
|
||||
physical_device, surface, sane_image_extent_limit);
|
||||
if (swapchain_details_res.variant != Result_Ok)
|
||||
abortf("swapchain_details_res.variant != Result_Ok");
|
||||
|
||||
@ -1082,7 +1284,7 @@ int main() {
|
||||
CamControlInfo my_cam_control_info = CamControlInfo_new();
|
||||
vec3 Buba_control_info = {0};
|
||||
|
||||
Jane jane = Jane_create(device);
|
||||
Jane_r0 jane = Jane_r0_create(device);
|
||||
|
||||
// Mainloop
|
||||
margaret_ns_time start = margaret_clock_gettime_monotonic_raw();
|
||||
@ -1182,11 +1384,11 @@ int main() {
|
||||
);
|
||||
if (aq_ret == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
fprintf(stderr, "vkAcquireNextImageKHR: VK_ERROR_OUT_OF_DATE_KHR\n");
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane);
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane, sane_image_extent_limit);
|
||||
continue;
|
||||
} else if (aq_ret == VK_SUBOPTIMAL_KHR) {
|
||||
fprintf(stderr, "vkAcquireNextImageKHR: VK_SUBOPTIMAL_KHR\n");
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane);
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane, sane_image_extent_limit);
|
||||
continue;
|
||||
} else if (aq_ret != VK_SUCCESS) {
|
||||
abortf("vkAcquireNextImageKHR");
|
||||
@ -1274,7 +1476,9 @@ int main() {
|
||||
};
|
||||
assert(ARRAY_SIZE(waiting_for_semaphores) == ARRAY_SIZE(waiting_stages));
|
||||
VkCommandBuffer command_buffers[1] = { rendering_command_buffer_1 };
|
||||
VkSemaphore signaling_semaphores[1] = { jane.render_finished_semaphore };
|
||||
VkSemaphore signaling_semaphores[1] = {
|
||||
*VecVkSemaphore_at(&swfb.rendering_finished_here_semaphores, ij)
|
||||
};
|
||||
VkSubmitInfo cmd_submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
|
||||
@ -1294,7 +1498,9 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
VkSemaphore waiting_for_semaphores[] = { jane.render_finished_semaphore };
|
||||
VkSemaphore waiting_for_semaphores[] = {
|
||||
*VecVkSemaphore_at(&swfb.rendering_finished_here_semaphores, ij)
|
||||
};
|
||||
VkSwapchainKHR swapchains[] = { swfb.swapchain };
|
||||
uint32_t image_indices[] = { ij };
|
||||
assert( ARRAY_SIZE(swapchains) == ARRAY_SIZE(image_indices) );
|
||||
@ -1314,11 +1520,11 @@ int main() {
|
||||
// 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(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane);
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane, sane_image_extent_limit);
|
||||
continue;
|
||||
} else if (pres_ret == VK_SUBOPTIMAL_KHR) {
|
||||
fprintf(stderr, "vkQueuePresentKHR: VK_SUBOPTIMAL_KHR\n");
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane);
|
||||
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb, &jane, sane_image_extent_limit);
|
||||
continue;
|
||||
} else if (pres_ret != VK_SUCCESS) {
|
||||
abortf("vkQueuePresentKHR");
|
||||
@ -1366,7 +1572,7 @@ int main() {
|
||||
vkFreeMemory(device, host_mem, NULL);
|
||||
vkDestroyCommandPool(device, command_pool, NULL);
|
||||
MargaretSwapchainBundle_drop_with_device(device, swfb);
|
||||
Jane_destroy(device, jane);
|
||||
Jane_r0_destroy(device, jane);
|
||||
destroy_graphics_pipeline_hands(device, pipeline_hands_1);
|
||||
vkDestroyRenderPass(device, render_pass_1, NULL);
|
||||
destroy_graphics_pipeline_hands(device, pipeline_hands_0);
|
||||
|
||||
@ -217,16 +217,19 @@ void try_drawing_frame(state_t *state){
|
||||
/* Draw checkerboxed background */
|
||||
uint32_t* data = state->swapchain.data + ij * MAX_BUFFER_WIDTH * MAX_BUFFER_HEIGHT;
|
||||
draw_frame(state, data, width, height);
|
||||
printf("Attached\n");
|
||||
wl_surface_attach(state->wl_surface, state->swapchain.used_buffers[ij], 0, 0);
|
||||
printf("Damaged\n");
|
||||
wl_surface_damage_buffer(state->wl_surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||
printf("Commited\n");
|
||||
wl_surface_commit(state->wl_surface);
|
||||
}
|
||||
|
||||
static void main_h_xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial){
|
||||
state_t *state = data;
|
||||
printf("XDG surface configured!\n");
|
||||
printf("Acknowledged surface configure\n");
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
// todo: synchronize with frame event
|
||||
state->swapchain.want_to_draw = true;
|
||||
try_drawing_frame(state);
|
||||
}
|
||||
@ -476,7 +479,7 @@ 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
|
||||
printf("AAA!!! CALLBACK!!!\n");
|
||||
state->wl_callback = wl_surface_frame(state->wl_surface);
|
||||
if (!state->wl_callback)
|
||||
abortf("wl_surface_frame\n");
|
||||
@ -551,6 +554,7 @@ int main() {
|
||||
abortf("xdg_surface_get_toplevel\n");
|
||||
xdg_toplevel_add_listener(state.xdg_toplevel, &main_h_xdg_toplevel_listener, &state);
|
||||
xdg_toplevel_set_title(state.xdg_toplevel, "r1");
|
||||
printf("Commited\n");
|
||||
wl_surface_commit(state.wl_surface);
|
||||
|
||||
state.wl_callback = wl_surface_frame(state.wl_surface);
|
||||
|
||||
@ -11,9 +11,6 @@
|
||||
#include "../../margaret/vulkan.h"
|
||||
#include <poll.h>
|
||||
|
||||
#define MAX_BUFFER_WIDTH 1000
|
||||
#define MAX_BUFFER_HEIGHT 800
|
||||
|
||||
|
||||
// todo: generate this function in l2
|
||||
VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_format) {
|
||||
@ -26,7 +23,7 @@ VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
.finalLayout = VK_IMAGE_L AYOUT_PRESENT_SRC_KHR,
|
||||
}
|
||||
};
|
||||
|
||||
@ -80,7 +77,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,
|
||||
@ -99,26 +96,25 @@ void reset_and_record_command_buffer_0(
|
||||
|
||||
typedef struct {
|
||||
VkSemaphore image_available_semaphore;
|
||||
VkSemaphore render_finished_semaphore;
|
||||
VkFence in_flight_fence;
|
||||
} Jane_r3;
|
||||
|
||||
NODISCARD Jane_r3 Jane_r3_create(VkDevice device) {
|
||||
return (Jane_r3){
|
||||
.image_available_semaphore = margaret_create_semaphore(device),
|
||||
.render_finished_semaphore = margaret_create_semaphore(device),
|
||||
.in_flight_fence = margaret_create_fence(device, true)
|
||||
};
|
||||
}
|
||||
|
||||
void Jane_r3_destroy(VkDevice device, Jane_r3 jane) {
|
||||
vkDestroyFence(device, jane.in_flight_fence, NULL);
|
||||
vkDestroySemaphore(device, jane.render_finished_semaphore, NULL);
|
||||
vkDestroySemaphore(device, jane.image_available_semaphore, NULL);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* Memory settings */
|
||||
VkExtent2D sane_image_extent_limit;
|
||||
/* Globals */
|
||||
struct wl_display *wl_display;
|
||||
struct wl_registry *wl_registry;
|
||||
@ -138,7 +134,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,38 +153,145 @@ 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) {
|
||||
}
|
||||
|
||||
void update_state(state_t* state, uint32_t fl) {
|
||||
const float width = (float)(state->width < MAX_BUFFER_WIDTH ? state->width : MAX_BUFFER_WIDTH);
|
||||
const float height = (float)(state->height < MAX_BUFFER_HEIGHT ? state->height : MAX_BUFFER_HEIGHT);
|
||||
float dur = (float)fl / 1000;
|
||||
state->ht += dur;
|
||||
}
|
||||
|
||||
// void try_drawing_frame(state_t *state){
|
||||
// if (!state->swapchain.want_to_draw)
|
||||
// return;
|
||||
// const int32_t width = state->width < MAX_BUFFER_WIDTH ? state->width : MAX_BUFFER_WIDTH;
|
||||
// const int32_t height = state->height < MAX_BUFFER_HEIGHT ? state->height : MAX_BUFFER_HEIGHT;
|
||||
|
||||
/* Draw checkerboxed background */
|
||||
// uint32_t* data = state->swapchain.data + ij * MAX_BUFFER_WIDTH * MAX_BUFFER_HEIGHT;
|
||||
// draw_frame(state, data, width, height);
|
||||
// wl_surface_attach(state->wl_surface, state->swapchain.used_buffers[ij], 0, 0);
|
||||
// wl_surface_damage_buffer(state->wl_surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||
// wl_surface_commit(state->wl_surface);
|
||||
// }
|
||||
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, state->sane_image_extent_limit);
|
||||
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);
|
||||
// printf("Dozhdalisya!\n");
|
||||
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");
|
||||
}
|
||||
// printf("Image acquired\n");
|
||||
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);
|
||||
|
||||
{
|
||||
VkSemaphore waiting_for_semaphores[1] = {state->jane.image_available_semaphore};
|
||||
VkPipelineStageFlags waiting_stages[1] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||
VkCommandBuffer command_buffers[1] = {state->rendering_command_buffer_0};
|
||||
VkSemaphore signaling_semaphores[1] = {
|
||||
*VecVkSemaphore_at(&state->swfb.rendering_finished_here_semaphores, ij)
|
||||
};
|
||||
VkSubmitInfo submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = waiting_for_semaphores,
|
||||
.pWaitDstStageMask = waiting_stages,
|
||||
|
||||
.commandBufferCount = ARRAY_SIZE(command_buffers),
|
||||
.pCommandBuffers = command_buffers,
|
||||
|
||||
.signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
|
||||
.pSignalSemaphores = signaling_semaphores,
|
||||
};
|
||||
if (vkQueueSubmit(state->graphics_queue, 1, &submit_info, state->jane.in_flight_fence) != VK_SUCCESS)
|
||||
abortf("vkQueueSubmit");
|
||||
}
|
||||
|
||||
{
|
||||
VkSemaphore waiting_for_semaphores[] = {
|
||||
*VecVkSemaphore_at(&state->swfb.rendering_finished_here_semaphores, ij)
|
||||
};
|
||||
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,
|
||||
};
|
||||
|
||||
// printf("Now I will present it\n");
|
||||
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_xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial){
|
||||
state_t *state = data;
|
||||
printf("XDG surface configured!\n");
|
||||
printf("XDG surface configured! (%d %d)\n", state->width, state->height);
|
||||
printf("Acknowledged surface configure\n");
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
// state->swapchain.want_to_draw = true;
|
||||
// try_drawing_frame(state);
|
||||
|
||||
vulkano_frame_drawing(state);
|
||||
// printf("Damaged\n");
|
||||
// wl_surface_damage_buffer(state->wl_surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||
// printf("Commited\n");
|
||||
// wl_surface_commit(state->wl_surface);
|
||||
}
|
||||
|
||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||
@ -195,8 +302,12 @@ static void main_h_xdg_toplevel_configure(
|
||||
void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states
|
||||
){
|
||||
state_t *state = data;
|
||||
uint32_t *conf_state;
|
||||
wl_array_for_each(conf_state, states) {
|
||||
printf("A state of xdg toplevel: %u\n", *conf_state);
|
||||
}
|
||||
printf("XDG toplevel configured to (%d %d)\n", width, height);
|
||||
if (width <= 0 || height < 0)
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
state->width = width;
|
||||
state->height = height;
|
||||
@ -403,34 +514,34 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
// printf("Damaged\n");
|
||||
// wl_surface_damage(state->wl_surface, 0, 0, state->width, state->height);
|
||||
// printf("Commited\n");
|
||||
// wl_surface_commit(state->wl_surface);
|
||||
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() {
|
||||
state_t state = { .width = 800, .height = 480 };
|
||||
state_t state = { .sane_image_extent_limit = {1000, 700}, .width = 800, .height = 480 };
|
||||
state.wl_display = wl_display_connect(NULL);
|
||||
|
||||
if (!state.wl_display)
|
||||
@ -460,18 +571,23 @@ int main() {
|
||||
abortf("xdg_surface_get_toplevel\n");
|
||||
xdg_toplevel_add_listener(state.xdg_toplevel, &main_h_xdg_toplevel_listener, &state);
|
||||
xdg_toplevel_set_title(state.xdg_toplevel, "r3");
|
||||
xdg_toplevel_set_app_id(state.xdg_toplevel, "r3");
|
||||
wl_surface_commit(state.wl_surface);
|
||||
|
||||
// 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);
|
||||
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);
|
||||
|
||||
// wl_surface_commit(state.wl_surface);
|
||||
// wl_display_roundtrip(state.wl_display);
|
||||
// wl_surface_commit(state.wl_surface);
|
||||
|
||||
state.vk_instance_and_debug = MargaretInstanceAndItsDebug_new(true);
|
||||
VkInstance vk_instance = state.vk_instance_and_debug.instance;
|
||||
state.vk_surface = margaret_create_surface(vk_instance, state.wl_display, state.wl_surface);
|
||||
state.physical_device = margaret_select_one_physical_device(vk_instance, state.vk_surface,
|
||||
cstr("nvidia"), cstr("NOT SPECIFIED"));
|
||||
cstr("nvidia"), cstr("NOT SPECIFIED"), state.sane_image_extent_limit);
|
||||
ResultMargaretChosenQueueFamiliesOrSpanU8 queue_fam_res = margaret_choose_good_queue_families(
|
||||
state.physical_device, state.vk_surface);
|
||||
if (queue_fam_res.variant != Result_Ok)
|
||||
@ -479,30 +595,35 @@ int main() {
|
||||
state.queue_fam = queue_fam_res.ok;
|
||||
state.device = margaret_create_logical_device(state.physical_device, state.queue_fam);
|
||||
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);
|
||||
vkGetDeviceQueue(state.device, state.queue_fam.for_presentation, 0, &state.presentation_queue);
|
||||
ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details(
|
||||
state.physical_device, state.vk_surface, state.sane_image_extent_limit);
|
||||
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){}};
|
||||
while (wl_display_dispatch(state.wl_display)) {
|
||||
// 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) >= 0) {
|
||||
if (state.closed)
|
||||
break;
|
||||
}
|
||||
// if (state.wl_callback)
|
||||
// wl_callback_destroy(state.wl_callback);
|
||||
printf("Finished!\n");
|
||||
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