X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fvulkan%2Fvk.cc;h=ce55be2417b33ee4138901d34247c06d8f679170;hb=ecb47604bb2b8ab3ac5a133e78ef6cb19a20d9cc;hp=3d9862de4d2a79e6d1ba41118100104a06bb3334;hpb=64e2adbbab48320b6cd792e515b44cea112a3be4;p=demo diff --git a/src/vulkan/vk.cc b/src/vulkan/vk.cc index 3d9862d..ce55be2 100644 --- a/src/vulkan/vk.cc +++ b/src/vulkan/vk.cc @@ -1,20 +1,707 @@ -#include "vulkan/vk.h" -extern GLFWwindow win; +#define GLFW_INCLUDE_VULKAN +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "allocator.h" +#include "gfxapi.h" +#include "image.h" +#include "vkutil.h" +#include "vk.h" + +/* global variables */ +extern GLFWwindow *win; +extern int win_w; +extern int win_h; + +//command buffers +static VkCommandBuffer init_buf; +static VkCommandBuffer rbufs[2]; +//depth buffer +static VkImage dimg; +static VkImageView dview; +static const VkFormat dformat = VK_FORMAT_D32_SFLOAT_S8_UINT; +//swapchain +static VkImage *images; +static VkImageView *iviews; +static uint32_t num_images; +//renderpass +static VkRenderPass rpass; +static VkFramebuffer fbs[2]; +//semaphores-drawing-presentation +static uint32_t curr_img; // current sc image +static VkSemaphore psema; + + +/* static variables */ +static VkDeviceMemory gpu_mem; // to be replaced when I fix the allocator +static Vec4 clear_color(1, 0.1, 0.1, 1.0); + +/* static functions */ +static void error_callback(int error, const char *descr); +static void clear(float r, float g, float b); +static void viewport(int x, int y, int width, int height); +static void zbuffer(bool enable); +static void cull_face(Gfx_cull_face cf); +static void reshape(int width, int height); +static void swapbuffers(); +static void begin_drawing(); +static void end_drawing(); + +static bool create_swapchain(VkSwapchainKHR *sc); +static bool create_zbuffer(); +static bool create_renderpass(); +static bool create_framebuffers(); +static bool begin_init_command_buffer(VkCommandBuffer *cb); +static bool end_init_command_buffer(VkCommandBuffer *cb); +static bool allocate_rendering_command_buffers(VkCommandBuffer *bufs); +static void free_rendering_command_buffers(VkCommandBuffer *bufs, int count); +static bool begin_rendering_command_buffers(VkCommandBuffer *bufs, int count); bool init_vulkan() { + if(!glfwInit()) { + fprintf(stderr, "Failed to initialize GLFW.\n"); + return false; + } + + if(!glfwVulkanSupported()) { + fprintf(stderr, "No Vulkan support on the device.\n"); + return false; + } + + //TODO: remove later + glfwSetErrorCallback(error_callback); + + /* create device and command pool! */ + if(!vku_create_device()) { + fprintf(stderr, "Failed to initialize vulkan.\n"); + return false; + } + + if(!glfwGetPhysicalDevicePresentationSupport(vkinst, vk_physical, vkqfamily)) { + fprintf(stderr, "Presentation support not found.\n"); + return false; + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + if(!(win = glfwCreateWindow(win_w, win_h, "vkcow", 0, 0))) { + fprintf(stderr, "Failed to create window.\n"); + return false; + } + + VkResult res = glfwCreateWindowSurface(vkinst, win, 0, &vk_surface); + if(res != VK_SUCCESS) { + fprintf(stderr, "Failed to create KHR surface: %s\n", vku_get_vulkan_error_str(res)); + return false; + } + + if(!create_swapchain(&vk_swapchain)) { + fprintf(stderr, "Failed to create swapchain.\n"); + return false; + } + + init_buf = VK_NULL_HANDLE; + if(!begin_init_command_buffer(&init_buf)) { + fprintf(stderr, "Failed to start VK_NULL_HANDLE command buffer.\n"); + return false; + } + + if(!create_zbuffer()) { + fprintf(stderr, "Failed to create depth buffer.\n"); + return false; + } + + if(!create_renderpass()) { + fprintf(stderr, "Failed to create the renderpass.\n"); + return false; + } + + if(!create_framebuffers()) { + fprintf(stderr, "Failed to create the framebuffer.\n"); + return false; + } + + if(!end_init_command_buffer(&init_buf)) { + fprintf(stderr, "Failed to end the command buffer.\n"); + return false; + } + + /* rendering command buffers */ + if(!allocate_rendering_command_buffers(rbufs)) { + fprintf(stderr, "Failed to allocate rendering command buffers.\n"); + return false; + } + + if(!begin_rendering_command_buffers(rbufs, 2)) { + fprintf(stderr, "Failed to begin rendering command buffers.\n"); + return false; + } + + gfx_clear = clear; + gfx_viewport = viewport; + gfx_zbuffer = zbuffer; + gfx_cull_face = cull_face; + gfx_reshape = reshape; + gfx_swapbuffers = swapbuffers; + gfx_begin_drawing = begin_drawing; + gfx_end_drawing = end_drawing; + + return true; +} + +static bool create_swapchain(VkSwapchainKHR *sc) +{ + /* surface capabilities */ + VkSurfaceCapabilitiesKHR scap; + if(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical, vk_surface, &scap) != VK_SUCCESS) { + fprintf(stderr, "Failed to get physical device surface capabilities\n"); + return false; + } + + /* presentation modes */ + uint32_t prmode_cnt; + if(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_physical, vk_surface, &prmode_cnt, 0) != VK_SUCCESS) { + fprintf(stderr, "Failed to get physical device surface presentation modes count.\n"); + return false; + } + + if(prmode_cnt == 0) { + fprintf(stderr, "Presentation modes not found.\n"); + return false; + } + + VkPresentModeKHR scmode = VK_PRESENT_MODE_FIFO_KHR; + VkPresentModeKHR *modes = new VkPresentModeKHR[prmode_cnt]; + + if(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_physical, vk_surface, &prmode_cnt, modes) != VK_SUCCESS) { + fprintf(stderr, "Failed to get physical device presentation modes.\n"); + return false; + } + + for(uint32_t i=0; i 0 && num_images > scap.maxImageCount) + num_images = scap.maxImageCount; + + printf("num_images : %u\n", num_images); + assert(num_images > 0); + + images = new VkImage[num_images]; + iviews = new VkImageView[num_images]; + + /* transform flags */ + VkSurfaceTransformFlagBitsKHR pre_transf = scap.currentTransform; + if(scap.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) + pre_transf = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + + /* find suitable colorspace, format */ + VkFormat format; + VkColorSpaceKHR colorspace; + + VkSurfaceFormatKHR sformat; + if(!vku_get_surface_format(vk_physical, vk_surface, &sformat)) { + return false; + } + + format = sformat.format; + colorspace = sformat.colorSpace; + + /* creating the swapchain */ + VkSwapchainCreateInfoKHR sinfo; + memset(&sinfo, 0, sizeof sinfo); + + sinfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + sinfo.surface = vk_surface; + sinfo.minImageCount = num_images; + sinfo.imageFormat = format; + sinfo.imageColorSpace = colorspace; + sinfo.imageExtent = scextent; + sinfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + sinfo.preTransform = pre_transf; + sinfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + sinfo.imageArrayLayers = 1; + sinfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + sinfo.presentMode = scmode; + sinfo.oldSwapchain = VK_NULL_HANDLE; //TODO + sinfo.clipped = VK_TRUE; //TODO + + if(vkCreateSwapchainKHR(vk_device, &sinfo, 0, sc) != VK_SUCCESS) { + fprintf(stderr, "Failed to create swapchain.\n"); + return false; + } + + if(vkGetSwapchainImagesKHR(vk_device, *sc, &num_images, 0) != VK_SUCCESS) { + fprintf(stderr, "Failed to get the number of the swapchain images.\n"); + return false; + } + + if(vkGetSwapchainImagesKHR(vk_device, *sc, &num_images, images) != VK_SUCCESS) { + fprintf(stderr, "Failed to get the swapchain images.\n"); + return false; + } + + VkImageViewCreateInfo ivinf; + memset(&ivinf, 0, sizeof ivinf); + ivinf.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + ivinf.format = format; + ivinf.components = { + VK_COMPONENT_SWIZZLE_R, + VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, + VK_COMPONENT_SWIZZLE_A + }; + ivinf.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + ivinf.subresourceRange.levelCount = 1; + ivinf.subresourceRange.layerCount = 1; + ivinf.viewType = VK_IMAGE_VIEW_TYPE_2D; + + for(uint32_t i=0; i