vulkan init done, more added to the platform layer for interfacing with window

This commit is contained in:
Matthew 2025-02-23 16:17:23 +11:00
parent 7bf35d0031
commit 5f235694cd
11 changed files with 556 additions and 6 deletions

2
.ignore Normal file
View File

@ -0,0 +1,2 @@
.git
build/

View File

@ -20,6 +20,23 @@ int main(int argc, char **argv)
Assert(CreateWindow(), "Failed to initialize the window"); Assert(CreateWindow(), "Failed to initialize the window");
Assert(InitRenderer(renderer_arena), "Failed to initialize the renderer"); Assert(InitRenderer(renderer_arena), "Failed to initialize the renderer");
b32 quit = false;
WindowEvent e;
while (!quit)
{
while (GetWindowEvent(&e))
{
switch (e.type)
{
case EVENT_QUIT:
quit = true;
break;
default:
break;
}
}
}
DestroyRenderer(); DestroyRenderer();
return 0; return 0;

View File

@ -91,3 +91,13 @@ Window *GetWindow()
{ {
return _GetWindow(); return _GetWindow();
} }
b32 GetWindowEvent(WindowEvent *event)
{
return _GetWindowEvent(event);
}
WindowSize GetWindowSize()
{
return _GetWindowSize();
}

View File

@ -1,5 +1,9 @@
#pragma once #pragma once
typedef enum Event_e Event_e;
typedef struct WindowEvent WindowEvent;
typedef struct WindowSize WindowSize;
#if __linux__ #if __linux__
#include "platform_linux.h" #include "platform_linux.h"
#endif #endif
@ -16,6 +20,28 @@
#error Not yet implemented #error Not yet implemented
#endif #endif
enum Event_e
{
EVENT_NONE = 0,
EVENT_QUIT,
EVENT_RESIZE,
};
struct WindowSize
{
u16 w;
u16 h;
};
struct WindowEvent
{
union
{
WindowSize resize;
};
Event_e type;
};
// Init // Init
b32 LoadLib(const char *name, Library *out_lib); b32 LoadLib(const char *name, Library *out_lib);
b32 LoadFn(const char *name, Library *lib, Function *out_fn); b32 LoadFn(const char *name, Library *lib, Function *out_fn);
@ -35,3 +61,5 @@ i32 EPrintf(const char *fmt, ...);
// Window Functions // Window Functions
b32 CreateWindow(); b32 CreateWindow();
Window *GetWindow(); Window *GetWindow();
b32 GetWindowEvent(WindowEvent *event);
WindowSize GetWindowSize();

View File

@ -227,4 +227,64 @@ Window *_GetWindow() {
return &linux_window; return &linux_window;
} }
WindowSize _GetWindowSize()
{
return (WindowSize) {
.w = linux_window.w,
.h = linux_window.h,
};
}
b32 _GetWindowEvent(WindowEvent *event)
{
Assert(event != NULL, "GetWindowEvent received a null pointer");
b32 valid_event = false;
b32 no_event = false;
do
{
xcb_generic_event_t *e = xcb_poll_for_event(linux_window.connection);
if (e != NULL)
{
switch (e->response_type & ~0x80)
{
case XCB_CLIENT_MESSAGE:
xcb_client_message_event_t *msg = (xcb_client_message_event_t *)e;
if (msg->data.data32[0] == linux_window.close_event)
{
event->type = EVENT_QUIT;
valid_event = true;
}
break;
case XCB_RESIZE_REQUEST:
event->type = EVENT_RESIZE;
valid_event = true;
xcb_resize_request_event_t *resize = (xcb_resize_request_event_t *)e;
if (resize->width > 0)
{
linux_window.w = resize->width;
event->resize.w = resize->width;
}
if (resize->height > 0)
{
linux_window.h = resize->height;
event->resize.h = resize->height;
}
break;
default:
break;
}
}
else
{
break;
}
} while(!valid_event);
return valid_event;
}

View File

@ -102,7 +102,8 @@ i32 _EPrintf(const char *fmt, va_list arg);
// Window Functions // Window Functions
b32 _CreateWindow(); b32 _CreateWindow();
Window *_GetWindow(); Window *_GetWindow();
b32 _GetWindowEvent(WindowEvent *event);
WindowSize _GetWindowSize();
// Platform API END // Platform API END

View File

@ -6,7 +6,6 @@
b32 _InitRenderer(Arena *arena) b32 _InitRenderer(Arena *arena)
{ {
Assert(InitVulkan(arena), "InitVkLib failure"); Assert(InitVulkan(arena), "InitVkLib failure");
ArenaFree(arena);
return true; return true;
} }
@ -27,7 +26,9 @@ void _DestroyRenderer()
static b32 InitVulkan(Arena *arena) static b32 InitVulkan(Arena *arena)
{ {
Assert(arena != NULL, "Vulkan memory is null"); Assert(arena != NULL, "Vulkan memory is null");
renderer.arena = arena; renderer.perm_arena = arena;
void *mem = ArenaAlloc(arena, MB(4));
renderer.arena = CreateArena(mem, MB(4));
Assert(InitVkGlobalFunctions(), "Unable to load vulkan functions"); Assert(InitVkGlobalFunctions(), "Unable to load vulkan functions");
Assert(vkCreateInstance(&inst_info, NULL, &renderer.vk.inst) == VK_SUCCESS, "Error initializing instance"); Assert(vkCreateInstance(&inst_info, NULL, &renderer.vk.inst) == VK_SUCCESS, "Error initializing instance");
@ -43,9 +44,17 @@ static b32 InitVulkan(Arena *arena)
Assert(CreateSurface(), "Unable to create surface"); Assert(CreateSurface(), "Unable to create surface");
Assert(CreateDevice(), "Unable to create device"); Assert(CreateDevice(), "Unable to create device");
Assert(CreateVmaAllocator(), "Unable to create VMA allocator"); Assert(CreateVmaAllocator(), "Unable to create VMA allocator");
Assert(CreateFrameStructures(), "Unable to create frame structures"); Assert(CreateFrameStructures(), "Unable to create frame structures");
Assert(CreateImmediateStructures(), "Unable to create immediate structures"); Assert(CreateImmediateStructures(), "Unable to create immediate structures");
Assert(CreateSwapchain(), "Unable to initialize swapchain and draw images");
ArenaFree(renderer.arena);
Printfln("yeah");
return true; return true;
} }
@ -84,7 +93,7 @@ static DeviceQueues CheckDeviceQueueSupport(VkPhysicalDevice device, VkSurfaceKH
u32 queue_count; u32 queue_count;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, NULL); vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, NULL);
VkQueueFamilyProperties *families = ArenaAlloc(renderer.arena, sizeof(VkQueueFamilyProperties) * queue_count); VkQueueFamilyProperties *families = ArenaAlloc(renderer.arena, sizeof(VkQueueFamilyProperties) * queue_count);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, &families[0]); vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, families);
for (i32 i = 0; i < queue_count; i++) for (i32 i = 0; i < queue_count; i++)
{ {
@ -115,7 +124,7 @@ static b32 CheckDevicePropertiesSupport(VkPhysicalDevice device, VkSurfaceKHR su
u32 ext_count; u32 ext_count;
vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, NULL); vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, NULL);
VkExtensionProperties *ext_properties = ArenaAlloc(renderer.arena, sizeof(VkExtensionProperties) * ext_count); VkExtensionProperties *ext_properties = ArenaAlloc(renderer.arena, sizeof(VkExtensionProperties) * ext_count);
vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, &ext_properties[0]); vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, ext_properties);
i32 matched = 0; i32 matched = 0;
for (u32 i = 0; i < ext_count; i++) { for (u32 i = 0; i < ext_count; i++) {
@ -179,7 +188,7 @@ static b32 CreateDevice()
u32 device_count; u32 device_count;
vkEnumeratePhysicalDevices(inst, &device_count, NULL); vkEnumeratePhysicalDevices(inst, &device_count, NULL);
VkPhysicalDevice *devices = ArenaAlloc(renderer.arena, sizeof(VkPhysicalDevice) * device_count); VkPhysicalDevice *devices = ArenaAlloc(renderer.arena, sizeof(VkPhysicalDevice) * device_count);
vkEnumeratePhysicalDevices(inst, &device_count, &devices[0]); vkEnumeratePhysicalDevices(inst, &device_count, devices);
b32 discrete_device = false; b32 discrete_device = false;
DeviceQueues *queues = &renderer.vk.queues; DeviceQueues *queues = &renderer.vk.queues;
@ -288,6 +297,8 @@ static b32 InitVkInstanceFunctions()
INIT_INST_FN(vkGetDeviceProcAddr); INIT_INST_FN(vkGetDeviceProcAddr);
INIT_INST_FN(vkDestroyInstance); INIT_INST_FN(vkDestroyInstance);
INIT_INST_FN(vkDestroySurfaceKHR); INIT_INST_FN(vkDestroySurfaceKHR);
INIT_INST_FN(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
INIT_INST_FN(vkGetPhysicalDeviceImageFormatProperties);
return true; return true;
} }
@ -364,6 +375,7 @@ static b32 CreateSurface()
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
Printf("Unable to create surface: %d", result); Printf("Unable to create surface: %d", result);
} }
Printfln("surface: %d", renderer.vk.surface);
return result == VK_SUCCESS; return result == VK_SUCCESS;
} }
@ -471,19 +483,185 @@ static b32 CreateImmediateStructures()
static b32 CreateSwapchain() static b32 CreateSwapchain()
{ {
Printfln("%d", __LINE__);
b32 success = true; b32 success = true;
VkSurfaceCapabilitiesKHR capabilities; VkPhysicalDevice phys_device = renderer.vk.phys_device;
VkDevice device = renderer.vk.device;
VkSurfaceKHR surface = renderer.vk.surface;
VkSurfaceCapabilitiesKHR capabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_device, surface, &capabilities);
Printfln("%d", __LINE__);
VkExtent2D extent;
WindowSize win_size = GetWindowSize();
extent.width = u32Clamp((u32)win_size.w, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
extent.height = u32Clamp((u32)win_size.h, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
u32 format_count;
vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface, &format_count, NULL);
VkSurfaceFormatKHR *formats = ArenaAlloc(renderer.arena, sizeof(VkSurfaceFormatKHR) * format_count);
vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface, &format_count, formats);
renderer.vk.sc_info.format = formats[0].format;
renderer.vk.sc_info.color_space = formats[0].colorSpace;
u32 present_count;
vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface, &present_count, NULL);
VkPresentModeKHR *present_modes = ArenaAlloc(renderer.arena, sizeof(VkSurfaceFormatKHR) * present_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface, &present_count, present_modes);
Printfln("%d", __LINE__);
VkPresentModeKHR present_mode;
for (u32 i = 0; i < present_count; i++)
{
if (present_modes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
{
present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
}
if (present_mode != VK_PRESENT_MODE_MAILBOX_KHR)
present_mode = VK_PRESENT_MODE_FIFO_KHR;
swapchain_create_info.minImageCount = capabilities.minImageCount + 1;
swapchain_create_info.surface = surface;
swapchain_create_info.imageFormat = renderer.vk.sc_info.format;
swapchain_create_info.imageColorSpace = renderer.vk.sc_info.color_space;
swapchain_create_info.imageExtent = extent;
swapchain_create_info.preTransform = capabilities.currentTransform;
swapchain_create_info.presentMode = present_mode;
VkResult result;
result = vkCreateSwapchainKHR(device, &swapchain_create_info, NULL, &renderer.vk.swapchain);
if (result != VK_SUCCESS)
success = false;
u32 image_count;
vkGetSwapchainImagesKHR(device, renderer.vk.swapchain, &image_count, NULL);
VkImage *sc_images = ArenaAlloc(renderer.perm_arena, sizeof(VkImage) * image_count);
VkImageView *sc_views = ArenaAlloc(renderer.perm_arena, sizeof(VkImage) * image_count);
vkGetSwapchainImagesKHR(device, renderer.vk.swapchain, &image_count, sc_images);
for (u32 i = 0; i < image_count; i++)
{
sc_image_view_create_info.image = sc_images[i];
sc_image_view_create_info.format = renderer.vk.sc_info.format;
result = vkCreateImageView(device, &sc_image_view_create_info, NULL, &sc_views[i]);
if (result != VK_SUCCESS)
success = false;
}
renderer.vk.sc_info.imgs = sc_images;
renderer.vk.sc_info.views = sc_views;
renderer.vk.sc_info.img_count = image_count;
VkFormat image_format = GetImageFormat();
VkExtent3D extent_3d = {
.width = extent.width,
.height = extent.height,
.depth = 1,
};
renderer.vk.sc_info.extent = extent_3d;
VmaAllocationCreateInfo alloc_create_info = {
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
};
// Draw Image
draw_image_create_info.format = image_format;
draw_image_create_info.extent = extent_3d;
result = vmaCreateImage(renderer.vk.alloc, &draw_image_create_info,
&alloc_create_info, &renderer.vk.sc_info.draw_img.img, &renderer.vk.sc_info.draw_img.alloc, NULL);
if (result != VK_SUCCESS)
success = false;
// Draw Image View
draw_image_view_create_info.image = renderer.vk.sc_info.draw_img.img;
draw_image_view_create_info.format = image_format;
result = vkCreateImageView(device, &draw_image_view_create_info, NULL, &renderer.vk.sc_info.draw_img.view);
if (result != VK_SUCCESS)
success = false;
// Depth Image
depth_image_create_info.extent = extent_3d;
result = vmaCreateImage(renderer.vk.alloc, &depth_image_create_info,
&alloc_create_info, &renderer.vk.sc_info.depth_img.img, &renderer.vk.sc_info.depth_img.alloc, NULL);
if (result != VK_SUCCESS)
success = false;
// Depth Image View
depth_image_view_create_info.image = renderer.vk.sc_info.depth_img.img;
result = vkCreateImageView(device, &depth_image_view_create_info, NULL, &renderer.vk.sc_info.depth_img.view);
if (result != VK_SUCCESS)
success = false;
return success; return success;
} }
static VkFormat GetImageFormat()
{
VkPhysicalDevice phys_device = renderer.vk.phys_device;
VkImageType image_type = VK_IMAGE_TYPE_2D;
VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
VkFormat format = 0;
for (i32 i = 0; i < Len(VK_IMAGE_FORMATS); i++)
{
VkImageFormatProperties properties;
VkResult result;
result = vkGetPhysicalDeviceImageFormatProperties(phys_device, VK_IMAGE_FORMATS[i], image_type,
tiling, usage_flags, 0, &properties);
if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
continue;
if (result == VK_SUCCESS)
{
format = VK_IMAGE_FORMATS[i];
break;
}
}
Assert(format != 0, "[Error] unable to find appropriate image format");
return format;
}
static void DestroyVulkan() static void DestroyVulkan()
{ {
VkDevice device = renderer.vk.device; VkDevice device = renderer.vk.device;
VkInstance instance = renderer.vk.inst; VkInstance instance = renderer.vk.inst;
FrameStructures data = renderer.vk.frame; FrameStructures data = renderer.vk.frame;
ImmediateStructures imm = renderer.vk.imm; ImmediateStructures imm = renderer.vk.imm;
SwapchainInfo sc_info = renderer.vk.sc_info;
VmaAllocator vma_alloc = renderer.vk.alloc;
VkSwapchainKHR swapchain = renderer.vk.swapchain;
vkDestroyImageView(device, sc_info.draw_img.view, NULL);
vmaDestroyImage(vma_alloc, sc_info.draw_img.img, sc_info.draw_img.alloc);
vkDestroyImageView(device, sc_info.depth_img.view, NULL);
vmaDestroyImage(vma_alloc, sc_info.depth_img.img, sc_info.depth_img.alloc);
for (u32 i = 0; i < sc_info.img_count; i++)
{
vkDestroyImageView(device, sc_info.views[i], NULL);
}
vkDestroySwapchainKHR(device, swapchain, NULL);
vkDestroyFence(device, imm.fence, NULL); vkDestroyFence(device, imm.fence, NULL);
vkFreeCommandBuffers(device, imm.pool, 1, &imm.buffer); vkFreeCommandBuffers(device, imm.pool, 1, &imm.buffer);
@ -511,6 +689,119 @@ static void DestroyVulkan()
vkDestroyInstance(renderer.vk.inst, NULL); vkDestroyInstance(renderer.vk.inst, NULL);
} }
const char *VkResultStr(VkResult result)
{
switch (result)
{
case VK_SUCCESS:
return "VK_SUCCESS";
case VK_NOT_READY:
return "VK_NOT_READY";
case VK_TIMEOUT:
return "VK_TIMEOUT";
case VK_EVENT_SET:
return "VK_EVENT_SET";
case VK_EVENT_RESET:
return "VK_EVENT_RESET";
case VK_INCOMPLETE:
return "VK_INCOMPLETE";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "VK_ERROR_OUT_OF_HOST_MEMORY";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
case VK_ERROR_INITIALIZATION_FAILED:
return "VK_ERROR_INITIALIZATION_FAILED";
case VK_ERROR_DEVICE_LOST:
return "VK_ERROR_DEVICE_LOST";
case VK_ERROR_MEMORY_MAP_FAILED:
return "VK_ERROR_MEMORY_MAP_FAILED";
case VK_ERROR_LAYER_NOT_PRESENT:
return "VK_ERROR_LAYER_NOT_PRESENT";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "VK_ERROR_EXTENSION_NOT_PRESENT";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "VK_ERROR_FEATURE_NOT_PRESENT";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "VK_ERROR_INCOMPATIBLE_DRIVER";
case VK_ERROR_TOO_MANY_OBJECTS:
return "VK_ERROR_TOO_MANY_OBJECTS";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
case VK_ERROR_FRAGMENTED_POOL:
return "VK_ERROR_FRAGMENTED_POOL";
case VK_ERROR_UNKNOWN:
return "VK_ERROR_UNKNOWN";
case VK_ERROR_OUT_OF_POOL_MEMORY:
return "VK_ERROR_OUT_OF_POOL_MEMORY";
case VK_ERROR_INVALID_EXTERNAL_HANDLE:
return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
case VK_ERROR_FRAGMENTATION:
return "VK_ERROR_FRAGMENTATION";
case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS:
return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
case VK_PIPELINE_COMPILE_REQUIRED:
return "VK_PIPELINE_COMPILE_REQUIRED";
case VK_ERROR_SURFACE_LOST_KHR:
return "VK_ERROR_SURFACE_LOST_KHR";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
case VK_SUBOPTIMAL_KHR:
return "VK_SUBOPTIMAL_KHR";
case VK_ERROR_OUT_OF_DATE_KHR:
return "VK_ERROR_OUT_OF_DATE_KHR";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "VK_ERROR_VALIDATION_FAILED_EXT";
case VK_ERROR_INVALID_SHADER_NV:
return "VK_ERROR_INVALID_SHADER_NV";
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
return "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR";
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR";
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR";
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR";
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR";
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
return "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR";
#endif
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
case VK_ERROR_NOT_PERMITTED_KHR:
return "VK_ERROR_NOT_PERMITTED_KHR";
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
case VK_THREAD_IDLE_KHR:
return "VK_THREAD_IDLE_KHR";
case VK_THREAD_DONE_KHR:
return "VK_THREAD_DONE_KHR";
case VK_OPERATION_DEFERRED_KHR:
return "VK_OPERATION_DEFERRED_KHR";
case VK_OPERATION_NOT_DEFERRED_KHR:
return "VK_OPERATION_NOT_DEFERRED_KHR";
case VK_ERROR_COMPRESSION_EXHAUSTED_EXT:
return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
case VK_RESULT_MAX_ENUM:
return "VK_RESULT_MAX_ENUM";
default:
return "??????";
}
}
static VkBool32 DebugCallback( static VkBool32 DebugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
VkDebugUtilsMessageTypeFlagsEXT message_type, VkDebugUtilsMessageTypeFlagsEXT message_type,

View File

@ -47,6 +47,7 @@ VK_DECLARE(vkEnumerateDeviceExtensionProperties);
VK_DECLARE(vkGetPhysicalDeviceSurfacePresentModesKHR); VK_DECLARE(vkGetPhysicalDeviceSurfacePresentModesKHR);
VK_DECLARE(vkGetPhysicalDeviceSurfaceFormatsKHR); VK_DECLARE(vkGetPhysicalDeviceSurfaceFormatsKHR);
VK_DECLARE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); VK_DECLARE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
VK_DECLARE(vkGetPhysicalDeviceImageFormatProperties);
#ifdef __linux__ #ifdef __linux__
VK_DECLARE(vkCreateXcbSurfaceKHR); VK_DECLARE(vkCreateXcbSurfaceKHR);
@ -137,16 +138,36 @@ typedef struct {
VkQueue graphics_queue, transfer_queue; VkQueue graphics_queue, transfer_queue;
} DeviceQueues; } DeviceQueues;
typedef struct {
VkImage img;
VkImageView view;
VmaAllocation alloc;
VkFormat fmt;
} Image;
typedef struct {
VkFormat format;
VkColorSpaceKHR color_space;
VkExtent3D extent;
VkImage *imgs;
VkImageView *views;
u32 img_count;
Image draw_img;
Image depth_img;
} SwapchainInfo;
typedef struct { typedef struct {
Library lib; Library lib;
VkInstance inst; VkInstance inst;
VkSurfaceKHR surface; VkSurfaceKHR surface;
VkDevice device; VkDevice device;
VkSwapchainKHR swapchain;
VkPhysicalDevice phys_device; VkPhysicalDevice phys_device;
DeviceQueues queues; DeviceQueues queues;
VmaAllocator alloc; VmaAllocator alloc;
FrameStructures frame; FrameStructures frame;
ImmediateStructures imm; ImmediateStructures imm;
SwapchainInfo sc_info;
#ifdef BUILD_DEBUG #ifdef BUILD_DEBUG
VkDebugUtilsMessengerEXT debug; VkDebugUtilsMessengerEXT debug;
#endif #endif
@ -155,6 +176,7 @@ typedef struct {
typedef struct { typedef struct {
Vulkan_t vk; Vulkan_t vk;
Arena *arena; Arena *arena;
Arena *perm_arena;
} Renderer_t; } Renderer_t;
// Renderer Function Declarations // Renderer Function Declarations
@ -167,6 +189,7 @@ static VkBool32 DebugCallback(
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData void *pUserData
); );
const char *VkResultStr(VkResult result);
// Init // Init
static b32 LoadVulkanLib(); static b32 LoadVulkanLib();
@ -184,6 +207,7 @@ static b32 CreateVmaAllocator();
static b32 CreateFrameStructures(); static b32 CreateFrameStructures();
static b32 CreateImmediateStructures(); static b32 CreateImmediateStructures();
static b32 CreateSwapchain(); static b32 CreateSwapchain();
static VkFormat GetImageFormat();
// Destroy // Destroy
static void DestroyVulkan(); static void DestroyVulkan();

View File

@ -78,3 +78,33 @@ void MemZero(void *ptr, isize size)
assert(test_ptr[i] == 0); assert(test_ptr[i] == 0);
} }
} }
u32 u32Min(u32 l, u32 r)
{
return l >= r ? r : l;
}
i32 i32Min(i32 l, i32 r)
{
return l >= r ? r : l;
}
u32 u32Max(u32 l, u32 r)
{
return l >= r ? l : r;
}
i32 i32Max(i32 l, i32 r)
{
return l >= r ? l : r;
}
i32 i32Clamp(i32 v, i32 min, i32 max)
{
return i32Min(max, i32Max(v, min));
}
u32 u32Clamp(u32 v, u32 min, u32 max)
{
return i32Min(max, i32Max(v, min));
}

View File

@ -17,3 +17,11 @@ i32 SPrintf(char *buf, rawptr fmt, ...);
// Memory Functions // Memory Functions
void MemZero(void *ptr, isize size); void MemZero(void *ptr, isize size);
// Math Functions
u32 u32Min(u32 l, u32 r);
i32 i32Min(i32 l, i32 r);
u32 u32Max(u32 l, u32 r);
i32 i32Max(i32 l, i32 r);
i32 i32Clamp(i32 v, i32 min, i32 max);
u32 u32Clamp(u32 v, u32 min, u32 max);

View File

@ -1,5 +1,11 @@
// VULKAN CONFIG // VULKAN CONFIG
static const VkFormat VK_IMAGE_FORMATS[] = {
VK_FORMAT_R16G16B16A16_UNORM,
VK_FORMAT_R8G8B8A8_UNORM,
};
static VkApplicationInfo app_info = { static VkApplicationInfo app_info = {
.sType = STYPE(APPLICATION_INFO), .sType = STYPE(APPLICATION_INFO),
.pApplicationName = "Video Game", .pApplicationName = "Video Game",
@ -110,3 +116,76 @@ static VkCommandBufferAllocateInfo cmd_buf_info = {
.commandBufferCount = 1, .commandBufferCount = 1,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
}; };
static VkSwapchainCreateInfoKHR swapchain_create_info = {
.sType = STYPE(SWAPCHAIN_CREATE_INFO_KHR),
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.clipped = VK_TRUE,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
static VkImageViewCreateInfo sc_image_view_create_info = {
.sType = STYPE(IMAGE_VIEW_CREATE_INFO),
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.components = {
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
},
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
static VkImageCreateInfo draw_image_create_info = {
.sType = STYPE(IMAGE_CREATE_INFO),
.imageType = VK_IMAGE_TYPE_2D,
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
};
static VkImageViewCreateInfo draw_image_view_create_info = {
.sType = STYPE(IMAGE_VIEW_CREATE_INFO),
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
static VkImageCreateInfo depth_image_create_info = {
.sType = STYPE(IMAGE_CREATE_INFO),
.imageType = VK_IMAGE_TYPE_2D,
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.format = VK_FORMAT_D32_SFLOAT,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
static VkImageViewCreateInfo depth_image_view_create_info = {
.sType = STYPE(IMAGE_VIEW_CREATE_INFO),
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = VK_FORMAT_D32_SFLOAT,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};