diff --git a/build.bat b/build.bat index 27d20b1..0ddb0b2 100644 --- a/build.bat +++ b/build.bat @@ -2,10 +2,10 @@ setlocal enabledelayedexpansion set vulkan_include=C:\VulkanSDK\1.4.304.1\Include - +set linker_flags=-incremental:no -opt:ref User32.lib kernel32.lib mkdir build pushd build cl /c /I ..\external\vma /I %vulkan_include% ..\external\vma\vma.cpp -cl /I ..\external ..\src\main.c +cl /DEBUG /I ..\external /I %vulkan_include% -DBUILD_DEBUG -DSTG_VULKAN_RENDERER ..\src\main.c /link %linker_flags% popd diff --git a/src/arena.c b/src/arena.c index 81140cc..e1b804e 100644 --- a/src/arena.c +++ b/src/arena.c @@ -1,7 +1,7 @@ static Arena *CreateArena(rawptr buffer, isize length) { Arena *arena = (Arena *)buffer; - buffer += ARENA_HEADER_SIZE; + buffer = PtrAdd(buffer, ARENA_HEADER_SIZE); arena->buffer = buffer; arena->length = length; diff --git a/src/game.c b/src/game.c index 63885f5..8d642aa 100644 --- a/src/game.c +++ b/src/game.c @@ -10,7 +10,7 @@ static void Run() rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size); Arena *renderer_arena = CreateArenaDebug(renderer_mem, MB(8), __LINE__); - Assert(CreateWindow(), "Failed to initialize the window"); + Assert(CreateSystemWindow(), "Failed to initialize the window"); Assert(InitRenderer(renderer_arena), "Failed to initialize the renderer"); b32 quit = false; diff --git a/src/platform.c b/src/platform.c index 4d47dbe..92e802a 100644 --- a/src/platform.c +++ b/src/platform.c @@ -82,12 +82,12 @@ i32 EPrintf(const char *fmt, ...) return result; } -b32 CreateWindow() +b32 CreatePlatformWindow() { return _CreateWindow(); } -Window *GetWindow() +Window *GetWindowPtr() { return _GetWindow(); } diff --git a/src/platform.h b/src/platform.h index 9557b23..e7114c7 100644 --- a/src/platform.h +++ b/src/platform.h @@ -61,12 +61,11 @@ i32 Printfln(const char *fmt, ...); i32 EPrintf(const char *fmt, ...); // Window Functions -b32 CreateWindow(); -Window *GetWindow(); +b32 CreateSystemWindow(); b32 GetWindowEvent(WindowEvent *event); void WaitForWindowEvent(WindowEvent *event); WindowSize GetWindowSize(); // Directory Functions b32 ChangeWorkingDir(const char *); -u8 *OpenFile(const char *); +u8 *OSOpenFile(const char *); diff --git a/src/platform_linux.c b/src/platform_linux.c index aaae720..577c81a 100644 --- a/src/platform_linux.c +++ b/src/platform_linux.c @@ -347,7 +347,7 @@ b32 ChangeWorkingDir(const char *) return success; } -u8 *OpenFile(const char *) +u8 *OSOpenFile(const char *) { u8 *bytes = NULL; diff --git a/src/platform_windows.c b/src/platform_windows.c index 62251eb..da91bd8 100644 --- a/src/platform_windows.c +++ b/src/platform_windows.c @@ -1,3 +1,7 @@ +HINSTANCE win32_instance = {}; + +Window win32_window = {}; + LRESULT CALLBACK WindowProc(HWND window, UINT message, WPARAM w_param, LPARAM l_param) { LRESULT result = 0; @@ -31,12 +35,176 @@ LRESULT CALLBACK WindowProc(HWND window, UINT message, WPARAM w_param, LPARAM l_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line, int show_code) { + win32_instance = instance; + WNDCLASS window_class = { - .style = CS_OWNDC|CS_HREDREAW|CS_VREDRAW, - .lpfnWndProc = , + .style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW, + .lpfnWndProc = WindowProc, .hInstance = instance, .lpszClassName = "GearsWindowClass", }; - + if (RegisterClass(&window_class)) + { + HWND window_handle = CreateWindowEx( + 0, + window_class.lpszClassName, + "Video Game", + WS_OVERLAPPEDWINDOW|WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + 0, + 0, + instance, + 0 + ); + + if (window_handle) + { + while (true) + { + MSG message; + BOOL message_result = GetMessage(&message, 0, 0, 0); + if (message_result > 0) + { + TranslateMessage(&message); + DispatchMessage(&message); + } + else + { + break; + } + } + } + } } + +b32 _LoadLib(const char *name, Library *out_lib) +{ + b32 success = true; + + out_lib->module = LoadLibraryA("vulkan-1.dll"); + if (!out_lib->module) + success = false; + + return success; +} + +b32 _LoadFn(const char *name, Library *lib, Function *out_fn) +{ + b32 success = true; + + out_fn->fn = GetProcAddress(lib->module, name); + if (!out_fn->fn) + success = false; + + return success; +} + +b32 _InitPlatform() +{ + b32 success = true; + + return success; +} + +rawptr _MemAlloc(isize size) +{ + return NULL; +} + +rawptr _MemAllocZeroed(isize size) +{ + return NULL; +} + +isize _GetPageSize() +{ + return 0; +} + +i32 _EPrint(void const *str) +{ + return 0; +} + +i32 _Printf(const char *fmt, ...) +{ + return 0; +} + +i32 _Printfln(const char *fmt, ...) +{ + return 0; +} + +i32 _EPrintf(const char *fmt, ...) +{ + return 0; +} + +b32 _CreateWindow() +{ + b32 success = true; + + WNDCLASS window_class = { + .style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW, + .lpfnWndProc = WindowProc, + .hInstance = win32_instance, + .lpszClassName = WINDOW_CLASS_NAME, + }; + + ATOM r_class_atom = RegisterClass(&window_class); + if (!r_class_atom) + success = false; + + if (success) + { + HWND window_handle = CreateWindowEx( + 0, + window_class.lpszClassName, + "Video Game", + WS_OVERLAPPEDWINDOW|WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + 0, + 0, + win32_instance, + 0 + ); + + if (!window_handle) + success = false; + else + win32_window.handle = window_handle; + } + + return success; +} + +Window *_GetWindow() +{ + return NULL; +} + +b32 _GetWindowEvent(WindowEvent *event) +{ + b32 success = true; + + return success; +} + +void _WaitForWindowEvent(WindowEvent *event) +{ + +} + +WindowSize _GetWindowSize() +{ + return (WindowSize){ .w = 0, .h = 0 }; +} + diff --git a/src/platform_windows.h b/src/platform_windows.h index 0ce2b46..db6d141 100644 --- a/src/platform_windows.h +++ b/src/platform_windows.h @@ -4,6 +4,8 @@ #include #include +#define WINDOW_CLASS_NAME "GearsWindowClass" + typedef int8_t i8; typedef int16_t i16; typedef int32_t i32; @@ -35,17 +37,18 @@ typedef void * rawptr; typedef struct { - i32 lib; + HMODULE module; } Library; typedef struct { - i32 win; + HINSTANCE instance; + HWND handle; } Window; typedef struct { - i32 fn; + FARPROC fn; } Function; b32 _LoadLib(const char *name, Library *out_lib); diff --git a/src/render_vulkan.c b/src/render_vulkan.c index 81155b3..c480b30 100644 --- a/src/render_vulkan.c +++ b/src/render_vulkan.c @@ -745,7 +745,7 @@ static b32 InitVkDeviceFunctions() { #ifdef __linux__ static b32 CreateSurface() { - Window *window = GetWindow(); + Window *window = GetWindowPtr(); VkXcbSurfaceCreateInfoKHR surface_info = { .sType = STYPE(XCB_SURFACE_CREATE_INFO_KHR), .connection = window->connection, @@ -759,6 +759,15 @@ static b32 CreateSurface() return result == VK_SUCCESS; } +#elif _WIN32 +static b32 CreateSurface() +{ + Window *window = GetWindowPtr(); + VkWin32SurfaceCreateInfoKHR surface_info = { + .sType = STYPE(WIN_32_SURFACE_CREATE_INFO_KHR), + .hinstance = + }; +} #endif static b32 LoadVulkanLib() @@ -770,7 +779,7 @@ static b32 LoadVulkanLib() lib_found = LoadLib(vulkan_libs[i], lib); if (lib_found) { lib_found = LoadFn("vkGetInstanceProcAddr", lib, &fn); - vkGetInstanceProcAddr = fn.fn; + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)fn.fn; break; } } diff --git a/src/render_vulkan.h b/src/render_vulkan.h index c3dbfd7..79f46d6 100644 --- a/src/render_vulkan.h +++ b/src/render_vulkan.h @@ -1,6 +1,15 @@ #pragma once +#if __linux__ + #define VK_USE_PLATFORM_XCB_KHR + +#elif _WIN32 + +#define VK_USE_PLATFORM_WIN32_KHR + +#endif + #define VK_NO_PROTOTYPES #include @@ -323,7 +332,9 @@ static char *vulkan_libs[] = { #endif #if _WIN32 -#error Not yet implemented +static char *vulkan_libs[] = { + "vulkan-1.dll", +}; #endif #if __APPLE__ || __MACH__ diff --git a/src/util.h b/src/util.h index a76d12a..650f7f5 100644 --- a/src/util.h +++ b/src/util.h @@ -17,6 +17,7 @@ #define BitEq(var, bits) (((var) & (bits)) == bits) #define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1))) #define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0) +#define PtrAdd(ptr, add) (((char *)ptr) + add) // Types diff --git a/src/vulkan_config.c b/src/vulkan_config.c index 76b6d15..b65b602 100644 --- a/src/vulkan_config.c +++ b/src/vulkan_config.c @@ -24,10 +24,19 @@ static const char *instance_layers[] = { static const char *instance_extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, + +#ifdef __linux__ VK_KHR_XCB_SURFACE_EXTENSION_NAME, +#endif + +#ifdef _WIN32 + VK_KHR_WIN32_SURFACE_EXTENSION_NAME, +#endif + #ifdef BUILD_DEBUG VK_EXT_DEBUG_UTILS_EXTENSION_NAME, #endif + }; static VkInstanceCreateInfo inst_info = { @@ -86,10 +95,15 @@ static const VkPhysicalDeviceFeatures vk_features = { .shaderStorageImageArrayDynamicIndexing = VK_TRUE }; -static VkPhysicalDeviceFeatures2 vk_features_2 = { +static const VkPhysicalDeviceFeatures2 vk_features_2 = { .sType = STYPE(PHYSICAL_DEVICE_FEATURES_2), .pNext = &vk_11_features, - .features = vk_features + .features = { + .shaderUniformBufferArrayDynamicIndexing = VK_TRUE, + .shaderSampledImageArrayDynamicIndexing = VK_TRUE, + .shaderStorageBufferArrayDynamicIndexing = VK_TRUE, + .shaderStorageImageArrayDynamicIndexing = VK_TRUE + }, }; static VkDeviceCreateInfo device_info = { @@ -293,88 +307,109 @@ static VkPipelineLayoutCreateInfo pipeline_layout_create_info = { // PIPELINES // -static VkDynamicState pipeline_dynamic_state[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; +#define PIPELINE_DYNAMIC_STATE { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR } + -static const VkPipelineDynamicStateCreateInfo pipeline_default_dyn_state_info = { - .sType = STYPE(PIPELINE_DYNAMIC_STATE_CREATE_INFO), - .pDynamicStates = pipeline_dynamic_state, - .dynamicStateCount = Len(pipeline_dynamic_state), -}; +static VkDynamicState pipeline_dynamic_state[] = PIPELINE_DYNAMIC_STATE; -const static VkPipelineInputAssemblyStateCreateInfo pipeline_default_assembly_info = { - .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - .primitiveRestartEnable = VK_FALSE, -}; +#define PIPELINE_DEFAULT_DYN_STATE_INFO { \ + .sType = STYPE(PIPELINE_DYNAMIC_STATE_CREATE_INFO), \ + .pDynamicStates = pipeline_dynamic_state, \ + .dynamicStateCount = Len(pipeline_dynamic_state), \ +} -const static VkPipelineRasterizationStateCreateInfo pipeline_default_rasterization_info = { - .sType = STYPE(PIPELINE_RASTERIZATION_STATE_CREATE_INFO), - .polygonMode = VK_POLYGON_MODE_FILL, - .lineWidth = 1.0, - .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, -}; +static VkPipelineDynamicStateCreateInfo pipeline_default_dyn_state_info = PIPELINE_DEFAULT_DYN_STATE_INFO; -const static VkPipelineMultisampleStateCreateInfo pipeline_default_multisample_info = { - .sType = STYPE(PIPELINE_MULTISAMPLE_STATE_CREATE_INFO), - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, - .minSampleShading = 1.0, - .alphaToCoverageEnable = VK_FALSE, - .alphaToOneEnable = VK_FALSE, -}; +#define PIPELINE_DEFAULT_ASSEMBLY_INFO { \ + .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), \ + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, \ + .primitiveRestartEnable = VK_FALSE, \ +} -const static VkPipelineDepthStencilStateCreateInfo pipeline_default_depth_info = { - .sType = STYPE(PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO), - .depthTestEnable = VK_TRUE, - .depthWriteEnable = VK_TRUE, - .depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL, - .depthBoundsTestEnable = VK_FALSE, - .stencilTestEnable = VK_FALSE, - .minDepthBounds = 0.0, - .maxDepthBounds = 1.0, -}; +static VkPipelineInputAssemblyStateCreateInfo pipeline_default_assembly_info = PIPELINE_DEFAULT_ASSEMBLY_INFO; -const static VkPipelineRenderingCreateInfo pipeline_default_rendering_info = { - .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), - .colorAttachmentCount = 1, - //.pColorAttachmentFormats = FORMAT - //.depthAttachmentFormat = DEPTH_FORMAT - // Do not forget these whatever you do -}; +#define PIPELINE_DEFAULT_RASTERIZATION_INFO { \ + .sType = STYPE(PIPELINE_RASTERIZATION_STATE_CREATE_INFO), \ + .polygonMode = VK_POLYGON_MODE_FILL, \ + .lineWidth = 1.0, \ + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, \ +} -const static VkPipelineColorBlendAttachmentState pipeline_default_blend_attach_state = { - .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - .blendEnable = VK_FALSE, -}; +static VkPipelineRasterizationStateCreateInfo pipeline_default_rasterization_info = PIPELINE_DEFAULT_RASTERIZATION_INFO; -const static VkPipelineColorBlendStateCreateInfo pipeline_default_blend_info = { - .sType = STYPE(PIPELINE_COLOR_BLEND_STATE_CREATE_INFO), - .logicOpEnable = VK_FALSE, - .logicOp = VK_LOGIC_OP_COPY, - .attachmentCount = 1, - .pAttachments = &pipeline_default_blend_attach_state, -}; +#define PIPELINE_DEFAULT_MULTISAMPLE_INFO { \ + .sType = STYPE(PIPELINE_MULTISAMPLE_STATE_CREATE_INFO), \ + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, \ + .minSampleShading = 1.0, \ + .alphaToCoverageEnable = VK_FALSE, \ + .alphaToOneEnable = VK_FALSE, \ +} -const static VkPipelineVertexInputStateCreateInfo pipeline_default_vertex_info = { - .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), -}; +static VkPipelineMultisampleStateCreateInfo pipeline_default_multisample_info = PIPELINE_DEFAULT_MULTISAMPLE_INFO; + +#define PIPELINE_DEFAULT_DEPTH_INFO { \ + .sType = STYPE(PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO), \ + .depthTestEnable = VK_TRUE, \ + .depthWriteEnable = VK_TRUE, \ + .depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL, \ + .depthBoundsTestEnable = VK_FALSE, \ + .stencilTestEnable = VK_FALSE, \ + .minDepthBounds = 0.0, \ + .maxDepthBounds = 1.0, \ +} + +static VkPipelineDepthStencilStateCreateInfo pipeline_default_depth_info = PIPELINE_DEFAULT_DEPTH_INFO; + +#define PIPELINE_DEFAULT_RENDERING_INFO { \ + .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), \ + .colorAttachmentCount = 1, \ +} + +static VkPipelineRenderingCreateInfo pipeline_default_rendering_info = PIPELINE_DEFAULT_RENDERING_INFO; + +#define PIPELINE_DEFAULT_BLEND_ATTACH_STATE { \ + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, \ + .blendEnable = VK_FALSE, \ +} + +static VkPipelineColorBlendAttachmentState pipeline_default_blend_attach_state = PIPELINE_DEFAULT_BLEND_ATTACH_STATE; + +#define PIPELINE_DEFAULT_BLEND_INFO { \ + .sType = STYPE(PIPELINE_COLOR_BLEND_STATE_CREATE_INFO), \ + .logicOpEnable = VK_FALSE, \ + .logicOp = VK_LOGIC_OP_COPY, \ + .attachmentCount = 1, \ + .pAttachments = &pipeline_default_blend_attach_state, \ +} + +static VkPipelineColorBlendStateCreateInfo pipeline_default_blend_info = PIPELINE_DEFAULT_BLEND_INFO; + +#define PIPELINE_DEFAULT_VERTEX_INFO { \ + .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), \ +} + +static VkPipelineVertexInputStateCreateInfo pipeline_default_vertex_info = PIPELINE_DEFAULT_VERTEX_INFO; + +#define PIPELINE_DEFAULT_VIEWPORT_INFO { \ + .sType = STYPE(PIPELINE_VIEWPORT_STATE_CREATE_INFO), \ + .viewportCount = 1, \ + .scissorCount = 1, \ +} + +const static VkPipelineViewportStateCreateInfo pipeline_default_viewport_info = PIPELINE_DEFAULT_VIEWPORT_INFO; -const static VkPipelineViewportStateCreateInfo pipeline_default_viewport_info = { - .sType = STYPE(PIPELINE_VIEWPORT_STATE_CREATE_INFO), - .viewportCount = 1, - .scissorCount = 1, -}; #define INIT_PIPELINE_DEFAULTS(pipeline) \ -static VkPipelineDynamicStateCreateInfo pipeline##_dynamic_info = pipeline_default_dyn_state_info; \ -static VkPipelineInputAssemblyStateCreateInfo pipeline##_assembly_info = pipeline_default_assembly_info; \ -static VkPipelineRasterizationStateCreateInfo pipeline##_rasterization_info = pipeline_default_rasterization_info; \ -static VkPipelineMultisampleStateCreateInfo pipeline##_multisample_info = pipeline_default_multisample_info; \ -static VkPipelineDepthStencilStateCreateInfo pipeline##_depth_info = pipeline_default_depth_info; \ -static VkPipelineRenderingCreateInfo pipeline##_rendering_info = pipeline_default_rendering_info; \ -static VkPipelineColorBlendStateCreateInfo pipeline##_blend_info = pipeline_default_blend_info; \ -static VkPipelineVertexInputStateCreateInfo pipeline##_vertex_info = pipeline_default_vertex_info; \ -static VkPipelineViewportStateCreateInfo pipeline##_viewport_info = pipeline_default_viewport_info; \ -static VkGraphicsPipelineCreateInfo pipeline##_create_info = { \ +VkPipelineDynamicStateCreateInfo pipeline##_dynamic_info = PIPELINE_DEFAULT_DYN_STATE_INFO; \ +VkPipelineInputAssemblyStateCreateInfo pipeline##_assembly_info = PIPELINE_DEFAULT_ASSEMBLY_INFO; \ +VkPipelineRasterizationStateCreateInfo pipeline##_rasterization_info = PIPELINE_DEFAULT_RASTERIZATION_INFO; \ +VkPipelineMultisampleStateCreateInfo pipeline##_multisample_info = PIPELINE_DEFAULT_MULTISAMPLE_INFO; \ +VkPipelineDepthStencilStateCreateInfo pipeline##_depth_info = PIPELINE_DEFAULT_DEPTH_INFO; \ +VkPipelineRenderingCreateInfo pipeline##_rendering_info = PIPELINE_DEFAULT_RENDERING_INFO; \ +VkPipelineColorBlendStateCreateInfo pipeline##_blend_info = PIPELINE_DEFAULT_BLEND_INFO; \ +VkPipelineVertexInputStateCreateInfo pipeline##_vertex_info = PIPELINE_DEFAULT_VERTEX_INFO; \ +VkPipelineViewportStateCreateInfo pipeline##_viewport_info = PIPELINE_DEFAULT_VIEWPORT_INFO; \ +VkGraphicsPipelineCreateInfo pipeline##_create_info = { \ .sType = STYPE(GRAPHICS_PIPELINE_CREATE_INFO), \ .pNext = &pipeline##_rendering_info, \ .pVertexInputState = &pipeline##_vertex_info, \