diff --git a/build.sh b/build.sh index eb60478..ec97310 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,7 @@ source_files="../src/main.c" include_flags="-I../src/ -I../external/ -L." # executable name -out_name="here" +out_name="GearWorks" # vma flags vma_ld="ld -static vma.o `g++ -print-file-name=libstdc++.a` -o vmastdc++.o" diff --git a/src/render_vulkan.c b/src/render_vulkan.c index 6327037..e74e24b 100644 --- a/src/render_vulkan.c +++ b/src/render_vulkan.c @@ -45,17 +45,14 @@ static b32 InitVulkan(Arena *arena) Assert(CreateSurface(), "Unable to create surface"); Assert(CreateDevice(), "Unable to create device"); - - Assert(CreateVmaAllocator(), "Unable to create VMA allocator"); Assert(CreateFrameStructures(), "Unable to create frame structures"); Assert(CreateImmediateStructures(), "Unable to create immediate structures"); Assert(CreateSwapchain(), "Unable to initialize swapchain and draw images"); + Assert(CreateDescriptors(), "Unable to initialize descriptors."); ArenaFree(renderer.arena); - Printfln("yeah"); - return true; } @@ -236,7 +233,7 @@ static b32 CreateDevice() count++; } - device_info.queueCreateInfoCount = count; +device_info.queueCreateInfoCount = count; device_info.pQueueCreateInfos = &queue_info[0]; VkResult result = vkCreateDevice(renderer.vk.phys_device, &device_info, NULL, &renderer.vk.device); @@ -245,7 +242,7 @@ static b32 CreateDevice() } else { - Assert(InitVkDeviceFunctions(), "Failed to initialize device functions"); +Assert(InitVkDeviceFunctions(), "Failed to initialize device functions"); vkGetDeviceQueue(renderer.vk.device, queues->graphics, 0, &queues->graphics_queue); vkGetDeviceQueue(renderer.vk.device, queues->transfer, 0, &queues->transfer_queue); success = true; @@ -356,6 +353,7 @@ static b32 InitVkDeviceFunctions() { INIT_DEV_FN(vkResetFences); INIT_DEV_FN(vkResetCommandBuffer); INIT_DEV_FN(vkFreeCommandBuffers); + INIT_DEV_FN(vkDestroyDescriptorSetLayout); return true; } @@ -375,7 +373,6 @@ static b32 CreateSurface() if (result != VK_SUCCESS) { Printf("Unable to create surface: %d", result); } - Printfln("surface: %d", renderer.vk.surface); return result == VK_SUCCESS; } @@ -483,7 +480,6 @@ static b32 CreateImmediateStructures() static b32 CreateSwapchain() { - Printfln("%d", __LINE__); b32 success = true; VkPhysicalDevice phys_device = renderer.vk.phys_device; VkDevice device = renderer.vk.device; @@ -491,7 +487,6 @@ static b32 CreateSwapchain() VkSurfaceCapabilitiesKHR capabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_device, surface, &capabilities); - Printfln("%d", __LINE__); VkExtent2D extent; WindowSize win_size = GetWindowSize(); @@ -504,16 +499,14 @@ static b32 CreateSwapchain() 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; + renderer.vk.sc.format = formats[0].format; + renderer.vk.sc.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++) { @@ -529,8 +522,8 @@ static b32 CreateSwapchain() 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.imageFormat = renderer.vk.sc.format; + swapchain_create_info.imageColorSpace = renderer.vk.sc.color_space; swapchain_create_info.imageExtent = extent; swapchain_create_info.preTransform = capabilities.currentTransform; swapchain_create_info.presentMode = present_mode; @@ -549,16 +542,16 @@ static b32 CreateSwapchain() 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; + sc_image_view_create_info.format = renderer.vk.sc.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; + renderer.vk.sc.imgs = sc_images; + renderer.vk.sc.views = sc_views; + renderer.vk.sc.img_count = image_count; VkFormat image_format = GetImageFormat(); VkExtent3D extent_3d = { @@ -567,7 +560,7 @@ static b32 CreateSwapchain() .depth = 1, }; - renderer.vk.sc_info.extent = extent_3d; + renderer.vk.sc.extent = extent_3d; VmaAllocationCreateInfo alloc_create_info = { .usage = VMA_MEMORY_USAGE_GPU_ONLY, @@ -579,15 +572,15 @@ static b32 CreateSwapchain() 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); + &alloc_create_info, &renderer.vk.sc.draw_img.img, &renderer.vk.sc.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.image = renderer.vk.sc.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); + result = vkCreateImageView(device, &draw_image_view_create_info, NULL, &renderer.vk.sc.draw_img.view); if (result != VK_SUCCESS) success = false; @@ -595,13 +588,13 @@ static b32 CreateSwapchain() 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); + &alloc_create_info, &renderer.vk.sc.depth_img.img, &renderer.vk.sc.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); + depth_image_view_create_info.image = renderer.vk.sc.depth_img.img; + result = vkCreateImageView(device, &depth_image_view_create_info, NULL, &renderer.vk.sc.depth_img.view); if (result != VK_SUCCESS) success = false; @@ -640,25 +633,72 @@ static VkFormat GetImageFormat() return format; } +static b32 CreateDescriptors() +{ + b32 success = true; + VkDevice device = renderer.vk.device; + VkResult result; + + result = vkCreateDescriptorPool(device, &desc_pool_info, NULL, &renderer.vk.desc.pool); + if (result != VK_SUCCESS) + success = false; + + result = vkCreateDescriptorSetLayout(device, &shared_layout_create_info, NULL, &renderer.vk.desc.layouts[DESC_TYPE_SHARED]); + if (result != VK_SUCCESS) + success = false; + + for (u32 i = DESC_TYPE_COMBINED_SAMPLER; i < DESC_TYPE_MAX; i++) + { + bindless_layout_binding.descriptorType = desc_type_map[i]; + result = vkCreateDescriptorSetLayout(device, &bindless_layout_create_info, NULL, &renderer.vk.desc.layouts[i]); + if (result != VK_SUCCESS) + success = false; + } + + set_allocate_info.descriptorPool = renderer.vk.desc.pool; + set_allocate_info.pSetLayouts = renderer.vk.desc.layouts; + + result = vkAllocateDescriptorSets(device, &set_allocate_info, renderer.vk.desc.sets); + if (result != VK_SUCCESS) + success = false; + + pipeline_layout_create_info.setLayoutCount = DESC_TYPE_MAX; + pipeline_layout_create_info.pSetLayouts = renderer.vk.desc.layouts; + + result = vkCreatePipelineLayout(device, &pipeline_layout_create_info, NULL, &renderer.vk.desc.pipeline_layout); + if (result != VK_SUCCESS) + success = false; + + return success; +} + static void DestroyVulkan() { VkDevice device = renderer.vk.device; VkInstance instance = renderer.vk.inst; FrameStructures data = renderer.vk.frame; ImmediateStructures imm = renderer.vk.imm; - SwapchainInfo sc_info = renderer.vk.sc_info; + SwapchainStructures sc = renderer.vk.sc; VmaAllocator vma_alloc = renderer.vk.alloc; VkSwapchainKHR swapchain = renderer.vk.swapchain; + DescriptorStructures desc = renderer.vk.desc; - vkDestroyImageView(device, sc_info.draw_img.view, NULL); - vmaDestroyImage(vma_alloc, sc_info.draw_img.img, sc_info.draw_img.alloc); + vkDestroyPipelineLayout(device, desc.pipeline_layout, NULL); + + for (u32 i = DESC_TYPE_SHARED; i < DESC_TYPE_MAX; i++) + vkDestroyDescriptorSetLayout(device, desc.layouts[i], NULL); - vkDestroyImageView(device, sc_info.depth_img.view, NULL); - vmaDestroyImage(vma_alloc, sc_info.depth_img.img, sc_info.depth_img.alloc); + vkDestroyDescriptorPool(device, desc.pool, NULL); - for (u32 i = 0; i < sc_info.img_count; i++) + vkDestroyImageView(device, sc.draw_img.view, NULL); + vmaDestroyImage(vma_alloc, sc.draw_img.img, sc.draw_img.alloc); + + vkDestroyImageView(device, sc.depth_img.view, NULL); + vmaDestroyImage(vma_alloc, sc.depth_img.img, sc.depth_img.alloc); + + for (u32 i = 0; i < sc.img_count; i++) { - vkDestroyImageView(device, sc_info.views[i], NULL); + vkDestroyImageView(device, sc.views[i], NULL); } vkDestroySwapchainKHR(device, swapchain, NULL); diff --git a/src/render_vulkan.h b/src/render_vulkan.h index 5490544..3a54c79 100644 --- a/src/render_vulkan.h +++ b/src/render_vulkan.h @@ -26,6 +26,7 @@ } while (0) #define FRAME_OVERLAP 2 +#define DESC_MAX_BINDINGS 256 // Macros END @@ -112,6 +113,7 @@ VK_DECLARE(vkQueueSubmit2); VK_DECLARE(vkResetFences); VK_DECLARE(vkResetCommandBuffer); VK_DECLARE(vkFreeCommandBuffers); +VK_DECLARE(vkDestroyDescriptorSetLayout); // Vulkan Functions END @@ -119,7 +121,50 @@ VK_DECLARE(vkFreeCommandBuffers); // Types -typedef struct { +typedef enum Pipeline_e +{ + PIPELINE_QUAD, + + PIPELINE_MAX, +} PipelineHandle; + +typedef enum DescType_e +{ + DESC_TYPE_SHARED, + DESC_TYPE_COMBINED_SAMPLER, + DESC_TYPE_STORAGE_IMAGE, + DESC_TYPE_UNIFORM, + + DESC_TYPE_MAX, +} DescType; + +typedef struct +{ + u16 *free; + u16 *used; +} DescBindings; + +typedef struct +{ + VkPipelineLayout pipeline_layout; + VkDescriptorPool pool; + VkDescriptorSetLayout layouts[DESC_TYPE_MAX]; + VkDescriptorSet sets[DESC_TYPE_MAX]; + DescBindings *bindings; + u16 bindings_count; +} DescriptorStructures; + +typedef struct +{ + Mat4 view_matrix; + VkDeviceAddress vertex_buf; + u32 img_ix; + u32 samp_ix; + u32 storage_ix; +} PushConst; + +typedef struct +{ VkCommandPool pools[FRAME_OVERLAP]; VkCommandBuffer buffers[FRAME_OVERLAP]; VkSemaphore swapchain_sems[FRAME_OVERLAP]; @@ -127,7 +172,8 @@ typedef struct { VkFence render_fences[FRAME_OVERLAP]; } FrameStructures; -typedef struct { +typedef struct +{ VkCommandPool pool; VkCommandBuffer buffer; VkFence fence; @@ -154,7 +200,7 @@ typedef struct { u32 img_count; Image draw_img; Image depth_img; -} SwapchainInfo; +} SwapchainStructures; typedef struct { Library lib; @@ -167,7 +213,8 @@ typedef struct { VmaAllocator alloc; FrameStructures frame; ImmediateStructures imm; - SwapchainInfo sc_info; + SwapchainStructures sc; + DescriptorStructures desc; #ifdef BUILD_DEBUG VkDebugUtilsMessengerEXT debug; #endif @@ -208,6 +255,7 @@ static b32 CreateFrameStructures(); static b32 CreateImmediateStructures(); static b32 CreateSwapchain(); static VkFormat GetImageFormat(); +static b32 CreateDescriptors(); // Destroy static void DestroyVulkan(); diff --git a/src/util.h b/src/util.h index deb00ba..19cd140 100644 --- a/src/util.h +++ b/src/util.h @@ -10,6 +10,52 @@ #define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1))) #define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0) +// Types + +typedef union +{ + struct { f32 r, g; }; + struct { f32 x, y; }; +} Vec2; + +typedef union +{ + struct { f32 x, y, z; }; + struct { f32 r, g, b; }; +} Vec3; + +typedef union +{ + struct { f32 x, y, z, w; }; + struct { f32 r, g, b, a; }; +} Vec4; + +typedef union +{ + struct { i32 x, y; }; + struct { i32 r, g; }; +} iVec2; + +typedef union +{ + struct { i32 x, y, z; }; + struct { i32 r, g, b; }; +} iVec3; + +typedef union +{ + struct { i32 x, y, z, w; }; + struct { i32 r, g, b, a; }; +} iVec4; + +typedef f32 Mat2[4]; +typedef f32 Mat3[9]; +typedef f32 Mat4[16]; + +typedef f64 dMat2[4]; +typedef f64 dMat3[9]; +typedef f64 dMat4[16]; + // String Functions u32 StrLen(const char *str); b32 StrEq(const char *l, const char *r); diff --git a/src/vulkan_config.c b/src/vulkan_config.c index 761bf2c..dc29d94 100644 --- a/src/vulkan_config.c +++ b/src/vulkan_config.c @@ -63,7 +63,12 @@ static VkPhysicalDeviceVulkan12Features vk_12_features = { .sType = STYPE(PHYSICAL_DEVICE_VULKAN_1_2_FEATURES), .pNext = &vk_13_features, .descriptorIndexing = VK_TRUE, - .bufferDeviceAddress = VK_TRUE + .bufferDeviceAddress = VK_TRUE, + .descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageImageUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingPartiallyBound = VK_TRUE, }; static VkPhysicalDeviceVulkan11Features vk_11_features = { @@ -189,3 +194,94 @@ static VkImageViewCreateInfo depth_image_view_create_info = { .layerCount = 1, }, }; + +// +// PIPELINES & DESCRIPTORS +// + +static VkDescriptorPoolSize descriptor_pool_sizes[] = { + { .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 4096 }, + { .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 4096}, + { .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = 4096}, + { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 4096}, +}; + +static VkDescriptorPoolCreateInfo desc_pool_info = { + .sType = STYPE(DESCRIPTOR_POOL_CREATE_INFO), + .poolSizeCount = Len(descriptor_pool_sizes), + .pPoolSizes = descriptor_pool_sizes, + .maxSets = 12, // Not sure if this is correct + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, +}; + +static VkDescriptorBindingFlags shared_desc_binding_flags[] = { + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, +}; + +static VkDescriptorSetLayoutBindingFlagsCreateInfo shared_layout_binding_flags_info = { + .sType = STYPE(DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO), + .bindingCount = Len(shared_desc_binding_flags), + .pBindingFlags = shared_desc_binding_flags, +}; + +static VkDescriptorSetLayoutBinding shared_layout_bindings[] = { + { .binding = 0, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, + { .binding = 1, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, + { .binding = 2, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, +}; + +static VkDescriptorSetLayoutCreateInfo shared_layout_create_info = { + .sType = STYPE(DESCRIPTOR_SET_LAYOUT_CREATE_INFO), + .pNext = &shared_layout_binding_flags_info, + .bindingCount = Len(shared_layout_bindings), + .pBindings = shared_layout_bindings, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, +}; + +static VkDescriptorType desc_type_map[DESC_TYPE_MAX] = { + [DESC_TYPE_COMBINED_SAMPLER] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + [DESC_TYPE_STORAGE_IMAGE] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + [DESC_TYPE_UNIFORM] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, +}; + +static VkDescriptorBindingFlags bindless_desc_binding_flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT; + +static VkDescriptorSetLayoutBindingFlagsCreateInfo bindless_layout_flag_create_info = { + .sType = STYPE(DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO), + .bindingCount = 1, + .pBindingFlags = &bindless_desc_binding_flags, +}; + +static VkDescriptorSetLayoutBinding bindless_layout_binding = { + .binding = 0, + .descriptorCount = 1024, + .stageFlags = VK_SHADER_STAGE_ALL, +}; + +static VkDescriptorSetLayoutCreateInfo bindless_layout_create_info = { + .sType = STYPE(DESCRIPTOR_SET_LAYOUT_CREATE_INFO), + .pNext = &bindless_layout_flag_create_info, + .bindingCount = 1, + .pBindings = &bindless_layout_binding, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, +}; + +static VkDescriptorSetAllocateInfo set_allocate_info = { + .sType = STYPE(DESCRIPTOR_SET_ALLOCATE_INFO), + .descriptorSetCount = DESC_TYPE_MAX, +}; + +static VkPushConstantRange push_const_range = { + .offset = 0, + .size = sizeof(PushConst), + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT, +}; + +static VkPipelineLayoutCreateInfo pipeline_layout_create_info = { + .sType = STYPE(PIPELINE_LAYOUT_CREATE_INFO), + .setLayoutCount = DESC_TYPE_MAX, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_const_range, +};