#include #include #include #include #include #include #include #include #include #define MESH_SIZE 36*2*4*4 float pos_y = 0.0; float pos_z = 0.0; float pos_x = 0.0; float rot_y = 0.0; float rot_x = 0.0; uint8_t key_pressed[10]; unsigned long long get_time() { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long unix_us = tv.tv_sec * 1000000 + tv.tv_usec; return unix_us; } void key_callback(GLFWwindow* win, int key, int scancode, int action, int mods) { if(key == GLFW_KEY_SPACE) { key_pressed[0] = action; } if(key == GLFW_KEY_LEFT_SHIFT) { key_pressed[1] = action; } if(key == GLFW_KEY_Q) { key_pressed[2] = action; } if(key == GLFW_KEY_E) { key_pressed[3] = action; } if(key == GLFW_KEY_W) { key_pressed[4] = action; } if(key == GLFW_KEY_S) { key_pressed[5] = action; } if(key == GLFW_KEY_A) { key_pressed[6] = action; } if(key == GLFW_KEY_D) { key_pressed[7] = action; } if(key == GLFW_KEY_R) { key_pressed[8] = action; } if(key == GLFW_KEY_F) { key_pressed[9] = action; } } int main() { //glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND); uint32_t glfw_res = glfwInit(); printf("glfwInit: (%d)\n", glfw_res); //glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); GLFWwindow* win = glfwCreateWindow(1920, 1080, "Hi!", NULL, NULL); glfwSetKeyCallback(win, key_callback); //printf("glfwCreateWindow: %s", win == NULL ? "NULL" : "SUCCESS"); printf("Start App\n"); printf("VK_API: %u\n", VK_API_VERSION_1_0); VkApplicationInfo application_info = { VK_STRUCTURE_TYPE_APPLICATION_INFO, NULL, "Hello Vulkan", VK_MAKE_VERSION( 1, 0, 0 ), "Hello Engine", VK_MAKE_VERSION( 1, 0, 0 ), VK_API_VERSION_1_0 // 4194304, }; uint32_t glfw_exts_count = 0; const char** glfw_exts = glfwGetRequiredInstanceExtensions(&glfw_exts_count); for(int i = 0; i < glfw_exts_count; i++) { printf("Using Ext %s\n", glfw_exts[i]); } VkInstanceCreateInfo instance_create_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, NULL, 0, &application_info, 0, NULL, glfw_exts_count, glfw_exts }; VkResult res; VkInstance vkins; printf("CreateInstance: (%ld)\n", vkCreateInstance(&instance_create_info, NULL, &vkins)); VkSurfaceKHR surface; { res = glfwCreateWindowSurface(vkins, win, NULL, &surface); printf("CreateWindowSurface: (%ld)\n", res); } VkPhysicalDevice pdev; { uint32_t num_d = 0; res = vkEnumeratePhysicalDevices(vkins, &num_d, NULL); printf("EnumeratePhysicalDevices 1: (%ld) %lu\n", res, num_d); VkPhysicalDevice* phys_devs = malloc(sizeof(VkPhysicalDevice) * num_d); res = vkEnumeratePhysicalDevices(vkins, &num_d, &phys_devs[0]); printf("EnumeratePhysicalDevices 2: (%ld) %lu\n", res, num_d); pdev = phys_devs[1]; } { VkPhysicalDeviceProperties dev_props; vkGetPhysicalDeviceProperties(pdev, &dev_props); printf("Vulkan v%lu.%lu.%lu at %s\n", VK_VERSION_MAJOR(dev_props.apiVersion), VK_VERSION_MINOR(dev_props.apiVersion), VK_VERSION_PATCH(dev_props.apiVersion), dev_props.deviceName); } uint32_t q_graphic = 0; { uint32_t num_q = 0; vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_q, NULL); printf("GetPhysicalDeviceQueueFamilyProperties 1: %lu\n", num_q); VkQueueFamilyProperties* qfam_props = malloc(sizeof(VkQueueFamilyProperties) * num_q); vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_q, &qfam_props[0]); printf("GetPhysicalDeviceQueueFamilyProperties 2: %lu\n", num_q); for(int i = 0; i < num_q; i++) { VkQueueFlags flags = qfam_props[i].queueFlags; if((flags & VK_QUEUE_GRAPHICS_BIT) != 0) { q_graphic = i; } printf("Queue Family %d: %lu Qs G:%d, C:%d, T:%d\n", i, qfam_props[i].queueCount, (flags & VK_QUEUE_GRAPHICS_BIT) != 0, (flags & VK_QUEUE_COMPUTE_BIT) != 0, (flags & VK_QUEUE_TRANSFER_BIT) != 0); } } VkDevice dev; { float q_prio = 1.0f; VkDeviceQueueCreateInfo q_creat_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, NULL, 0, q_graphic, 1, &q_prio }; const char* const dev_extensions[] = {"VK_KHR_swapchain"}; VkPhysicalDeviceFeatures features = {}; vkGetPhysicalDeviceFeatures(pdev, &features); // if(features.depthClamp == VK_FALSE) { // fprintf(stderr, "depthClamp is not supported!\n"); // exit(1); // } VkDeviceCreateInfo dev_creat_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, NULL, 0, 1, &q_creat_info, 0, NULL, 1, dev_extensions, &features }; res = vkCreateDevice(pdev, &dev_creat_info, NULL, &dev); printf("CreateDevice: (%ld)\n", res); } VkQueue queue; vkGetDeviceQueue(dev, q_graphic, 0, &queue); VkCommandPoolCreateInfo cmd_pool_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, q_graphic }; VkCommandPool pool; res = vkCreateCommandPool(dev, &cmd_pool_info, NULL, &pool); printf("CreateCommandPool: (%ld)\n", res); VkCommandBufferAllocateInfo cmd_alloc_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, NULL, pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 }; VkCommandBuffer cmd_buf; res = vkAllocateCommandBuffers(dev, &cmd_alloc_info, &cmd_buf); printf("AllocateCommandBuffers: (%ld)\n", res); printf("Finding Host Visible Memory:"); uint32_t mem_inx = 0; { uint8_t sel = 0; VkPhysicalDeviceMemoryProperties mem_props; vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props); printf("Memory Type Count: %03d\n", mem_props.memoryTypeCount); printf("Memory Heap Count: %03d\n", mem_props.memoryHeapCount); for(int i = 0; i < mem_props.memoryTypeCount; i++) { VkMemoryType mem_type = mem_props.memoryTypes[i]; VkMemoryPropertyFlags flags = mem_type.propertyFlags; VkMemoryHeap heap = mem_props.memoryHeaps[mem_type.heapIndex]; if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 && (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0 && (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0) { if(!sel) { mem_inx = i; sel = 1; } printf("Found Memory Type: "); } else { printf(" "); } printf("Memory Type (%018p) %03d: SIZE: %lluMiB DLO:%d, HVI:%d, HCO:%d, HCA:%d, LAL:%d, PRO:%d\n", flags, i, heap.size/1024/1024, (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0, (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0, (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0, (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0, (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0, (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0); } } printf("Selected Host Visible Memory Type: %03d\n", mem_inx); printf("Finding Host Invisible Memory:"); uint32_t mem_depth_inx = 0; { uint8_t sel = 0; VkPhysicalDeviceMemoryProperties mem_props; vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props); printf("Memory Type Count: %03d\n", mem_props.memoryTypeCount); printf("Memory Heap Count: %03d\n", mem_props.memoryHeapCount); for(int i = 0; i < mem_props.memoryTypeCount; i++) { VkMemoryType mem_type = mem_props.memoryTypes[i]; VkMemoryPropertyFlags flags = mem_type.propertyFlags; VkMemoryHeap heap = mem_props.memoryHeaps[mem_type.heapIndex]; if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 && (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0 && (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) { if(!sel) { mem_depth_inx = i; sel = 1; } printf("Found Memory Type: "); } else { printf(" "); } printf("Memory Type (%018p) %03d: SIZE: %lluMiB DLO:%d, HVI:%d, HCO:%d, HCA:%d, LAL:%d, PRO:%d\n", flags, i, heap.size/1024/1024, (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0, (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0, (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0, (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0, (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0, (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0); } } printf("Selected Host Invisible Memory Type: %03d\n", mem_depth_inx); VkDeviceMemory dmem; { VkMemoryAllocateInfo mem_alloc_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, MESH_SIZE, mem_inx }; res = vkAllocateMemory(dev, &mem_alloc_info, NULL, &dmem); printf("AllocateMemory 1: (%ld)\n", res); } VkDeviceMemory depth_mem; { VkMemoryAllocateInfo mem_alloc_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, 1920*1080*8, // idk, apparently in Vulkan sizeof(VK_FORMAT_D32_SFLOAT) = 8. mem_depth_inx }; res = vkAllocateMemory(dev, &mem_alloc_info, NULL, &depth_mem); printf("AllocateMemory 2: (%ld)\n", res); } VkImage depth_img; { VkImageCreateInfo img_creat_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, VK_IMAGE_TYPE_2D, VK_FORMAT_D32_SFLOAT, {1920, 1080, 1}, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &q_graphic, VK_IMAGE_LAYOUT_UNDEFINED }; res = vkCreateImage(dev, &img_creat_info, NULL, &depth_img); printf("CreateImage: (%ld)\n", res); } { res = vkBindImageMemory(dev, depth_img, depth_mem, 0); printf("BindImageMemory: (%ld)\n", res); } VkImageView depth_view; { VkImageViewCreateInfo image_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, depth_img, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT, {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1} }; res = vkCreateImageView(dev, &image_info, NULL, &depth_view); printf("CreateImageView 1: (%ld)\n", res); } VkBuffer vbuf; { VkBufferCreateInfo buf_creat_info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, MESH_SIZE, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 0, NULL }; res = vkCreateBuffer(dev, &buf_creat_info, NULL, &vbuf); printf("CreateBuffer: (%ld)\n", res); } { res = vkBindBufferMemory(dev, vbuf, dmem, 0); printf("BindBufferMemory: (%ld)\n", res); } char* buf_mem = malloc(MESH_SIZE); memset(buf_mem, 0, MESH_SIZE); { res = vkMapMemory(dev, dmem, 0, VK_WHOLE_SIZE, 0, (void**)&buf_mem); printf("MapMemory: (%ld)\n", res); } float positions[] = { // BOTTOM -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 1.0, 0.0, 0.0, -0.5, 0.5, 2.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 1.0, 0.0, 0.0, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // TOP 0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, 2.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, // FRONT -0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, -0.5, 0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.5, 0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, -0.5, -0.5, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, // BACK 0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, -0.5, -0.5, 2.0, 1.0, 0.0, 0.0, 1.0, 0.0, // LEFT -0.5, -0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, -0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, 0.5, 2.0, 1.0, -1.0, 0.0, 0.0, 0.0, -0.5, -0.5, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, // RIGHT 0.5, 0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, }; memcpy(buf_mem, positions, sizeof(positions)); FILE* vert_shader_file = fopen("./vert.spv", "r"); if(vert_shader_file == NULL) { perror("Failed to read vertex shader"); exit(1); } fseek(vert_shader_file, 0, SEEK_END); long vert_shader_size = ftell(vert_shader_file); fseek(vert_shader_file, 0, SEEK_SET); uint8_t* vert_shader_bytes = malloc(vert_shader_size); fread(vert_shader_bytes, 1, vert_shader_size, vert_shader_file); printf("Vertex Shader Size: %db\n", vert_shader_size); VkShaderModule vert_mod; { VkShaderModuleCreateInfo vert_shader_mod_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, vert_shader_size, (uint32_t*)vert_shader_bytes }; res = vkCreateShaderModule(dev, &vert_shader_mod_info, NULL, &vert_mod); printf("CreateShaderModule: (%ld)\n", res); } free(vert_shader_bytes); FILE* frag_shader_file = fopen("./frag.spv", "r"); if(frag_shader_file == NULL) { perror("Failed to read fragment shader"); exit(1); } fseek(frag_shader_file, 0, SEEK_END); long frag_shader_size = ftell(frag_shader_file); fseek(frag_shader_file, 0, SEEK_SET); uint8_t* frag_shader_bytes = malloc(frag_shader_size); fread(frag_shader_bytes, 1, frag_shader_size, frag_shader_file); printf("Fragment Shader Size: %db\n", frag_shader_size); VkShaderModule frag_mod; { VkShaderModuleCreateInfo frag_shader_mod_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, frag_shader_size, (uint32_t*)frag_shader_bytes }; res = vkCreateShaderModule(dev, &frag_shader_mod_info, NULL, &frag_mod); printf("CreateShaderModule: (%ld)\n", res); } free(frag_shader_bytes); VkDescriptorSetLayout set_layouts[1]; { VkDescriptorSetLayoutBinding layout_bindings[] = { { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL } }; VkDescriptorSetLayoutCreateInfo layout_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, sizeof(layout_bindings)/sizeof(layout_bindings[0]), &layout_bindings[0] }; res = vkCreateDescriptorSetLayout(dev, &layout_info, NULL, &set_layouts[0]); printf("CreateDescriptorSetLayout: (%ld)\n", res); } VkPipelineLayout pipe_layout; { VkPushConstantRange push_range[] = {{VK_SHADER_STAGE_VERTEX_BIT, 0, 64+16}, {VK_SHADER_STAGE_FRAGMENT_BIT, 64+16, 16}}; VkPipelineLayoutCreateInfo pipe_layout_info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, NULL, 0, sizeof(set_layouts)/sizeof(set_layouts[0]), &set_layouts[0], 2, push_range }; res = vkCreatePipelineLayout(dev, &pipe_layout_info, NULL, &pipe_layout); printf("CreatePipelineLayout: (%ld)\n", res); } VkRenderPass pass; { VkAttachmentDescription color_attach = { 0, VK_FORMAT_B8G8R8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR }; VkAttachmentDescription depth_attach = { 0, VK_FORMAT_D32_SFLOAT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; VkAttachmentReference color_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; VkAttachmentReference depth_ref = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; VkSubpassDescription subpass_info = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, NULL, 1, &color_ref, NULL, &depth_ref, 0, NULL }; VkSubpassDependency sub_dep = { VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0 }; VkAttachmentDescription attaches[] = {color_attach, depth_attach}; VkRenderPassCreateInfo pass_info = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, 2, &attaches[0], 1, &subpass_info, 1, &sub_dep }; res = vkCreateRenderPass(dev, &pass_info, NULL, &pass); printf("CreateRenderPass: (%ld)\n", res); } VkViewport main_viewport = { 0, 0, 1920, 1080, 0.0f, 1.0f }; VkRect2D main_scissor = { {0,0}, {1920, 1080} }; VkPipeline pipe; { VkPipelineShaderStageCreateInfo vert_shader_stage_info = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_VERTEX_BIT, vert_mod, "main", NULL }; VkPipelineShaderStageCreateInfo frag_shader_stage_info = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_FRAGMENT_BIT, frag_mod, "main", NULL }; VkPipelineShaderStageCreateInfo stages[] = {vert_shader_stage_info, frag_shader_stage_info}; VkPipelineVertexInputStateCreateInfo vertex_input = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, NULL, 0, 0, NULL, 0, NULL }; VkPipelineInputAssemblyStateCreateInfo input_assembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL, 0, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE }; // IDK //VkPipelineTessellationStateCreateInfo tesselation = { // VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // NULL, // 0, // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // 0 //}; VkPipelineViewportStateCreateInfo viewport = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL, 0, 1, &main_viewport, 1, &main_scissor }; VkPipelineRasterizationStateCreateInfo rasterization = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, NULL, 0, VK_FALSE, VK_FALSE, VK_POLYGON_MODE_FILL, VK_CULL_MODE_FRONT_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, VK_FALSE, 0.0f, 0.0f, 0.0f, 1.0f }; VkPipelineMultisampleStateCreateInfo multisample = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, NULL, 0, VK_SAMPLE_COUNT_1_BIT, VK_FALSE, 0.0f, VK_FALSE, VK_FALSE }; VkPipelineDepthStencilStateCreateInfo depth_stencil = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, NULL, 0, VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS, VK_TRUE, VK_FALSE, {}, {}, 0.0f, 1.0f }; VkPipelineColorBlendAttachmentState blend_attachment = { VK_FALSE, VK_BLEND_FACTOR_SRC_COLOR, VK_BLEND_FACTOR_SRC_COLOR, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_SRC_COLOR, VK_BLEND_FACTOR_SRC_COLOR, VK_BLEND_OP_ADD, VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT }; VkPipelineColorBlendStateCreateInfo color_blend = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, NULL, 0, VK_FALSE, VK_LOGIC_OP_COPY, 1, &blend_attachment, {1.0, 1.0, 1.0, 1.0} }; VkGraphicsPipelineCreateInfo pipe_info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, NULL, 0,// VkPipelineCreateFlags 2, &stages[0], &vertex_input, // Vertex Input &input_assembly, // Input Assembly NULL, // Tesselation &viewport, // Viewport &rasterization, // Rasterization &multisample, // Multisample &depth_stencil, // Depth Stencil &color_blend, // Color Blend NULL, // Dynamic pipe_layout, pass, // VkRenderPass 0, // Subpass 0, 0 }; res = vkCreateGraphicsPipelines(dev, NULL, 1, &pipe_info, NULL, &pipe); printf("vkCreateGraphicsPipelines: (%ld)\n", res); } VkSwapchainKHR swapchain; { VkSurfaceCapabilitiesKHR caps; res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface, &caps); printf("GetPhysicalDeviceSurfaceCapabilitiesKHR: (%ld)\n", res); printf("minImageCount: %d\n", caps.minImageCount); uint32_t formats_count; res = vkGetPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, 0); printf("GetPhysicalDeviceSurfaceFormatsKHR 1: (%ld)\n", res); VkSurfaceFormatKHR* formats = malloc(formats_count * sizeof(VkSurfaceFormatKHR)); res = vkGetPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, &formats[0]); printf("GetPhysicalDeviceSurfaceFormatsKHR 2: (%ld)\n", res); for(int i = 0; i < formats_count; i++) { printf("Format %d: %d,%d;%d,%d\n", i, VK_FORMAT_B8G8R8A8_UNORM, formats[i].format, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, formats[i].colorSpace); } VkSwapchainCreateInfoKHR swap_info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, NULL, 0, surface, caps.minImageCount, VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, {1920, 1080}, 1, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SHARING_MODE_EXCLUSIVE, 0, NULL, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_TRUE, NULL }; res = vkCreateSwapchainKHR(dev, &swap_info, NULL, &swapchain); printf("vkCreateSwapchainKHR: (%ld)\n", res); } VkDescriptorPool desc_pool; { VkDescriptorPoolSize pool_sizes[] = { { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 } }; VkDescriptorPoolCreateInfo desc_pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, NULL, 0, 1, 1, &pool_sizes[0] }; res = vkCreateDescriptorPool(dev, &desc_pool_info, NULL, &desc_pool); printf("CreateDescriptorPool: (%ld)\n", res); } VkImage* swap_images = {}; uint32_t swap_img_count; { res = vkGetSwapchainImagesKHR(dev, swapchain, &swap_img_count, NULL); printf("GetSwapchainImagesKHR 1: (%ld)\n", res); printf("Swapchain Size: %d\n", swap_img_count); size_t size = swap_img_count * sizeof(VkImage); printf("Allocating VkImage: %zu\n", size); swap_images = malloc(size); res = vkGetSwapchainImagesKHR(dev, swapchain, &swap_img_count, &swap_images[0]); printf("GetSwapchainImagesKHR 2: (%ld)\n", res); } VkImageView* image_view; { size_t size = swap_img_count * sizeof(VkImageView); printf("Allocating VkImageView: %zu\n", size); image_view = malloc(size); } for(int i = 0; i < swap_img_count; i++) { VkImageViewCreateInfo image_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, swap_images[i], VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} }; res = vkCreateImageView(dev, &image_info, NULL, &image_view[i]); printf("CreateImageView 2 %d: (%ld)\n", i, res); } VkFramebuffer* framebuffers; { size_t size = swap_img_count * sizeof(VkFramebuffer); printf("Allocating VkFramebuffer: %zu\n", size); framebuffers = malloc(size); } for(int i = 0; i < swap_img_count; i++) { VkImageView image_views[] = {image_view[i], depth_view}; VkFramebufferCreateInfo framebuffer_info = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, pass, 2, image_views, 1920, 1080, 1 }; res = vkCreateFramebuffer(dev, &framebuffer_info, NULL, &framebuffers[i]); printf("CreateFramebuffer %d: (%ld)\n", i, res); } VkDescriptorSet desc_sets[1]; { VkDescriptorSetAllocateInfo desc_set_alloc_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, NULL, desc_pool, 1, &set_layouts[0] }; res = vkAllocateDescriptorSets(dev, &desc_set_alloc_info, &desc_sets[0]); printf("AllocateDescriptorSets: (%ld)\n", res); } { VkDescriptorBufferInfo buf_infos[] = { vbuf, 0, VK_WHOLE_SIZE }; VkWriteDescriptorSet desc_writes[] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, desc_sets[0], 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &buf_infos[0], NULL }; vkUpdateDescriptorSets(dev, 1, &desc_writes[0], 0, NULL); } VkSemaphore sem_avail; VkSemaphore sem_finish; VkFence fence_flight; { VkSemaphoreCreateInfo sem_info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, NULL, 0 }; res = vkCreateSemaphore(dev, &sem_info, NULL, &sem_avail); printf("CreateSemaphore 1: (%ld)\n", res); } { VkSemaphoreCreateInfo sem_info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, NULL, 0 }; res = vkCreateSemaphore(dev, &sem_info, NULL, &sem_finish); printf("CreateSemaphore 2: (%ld)\n", res); } { VkFenceCreateInfo fence_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, NULL, VK_FENCE_CREATE_SIGNALED_BIT }; res = vkCreateFence(dev, &fence_info, NULL, &fence_flight); printf("CreateFence: (%ld)\n", res); } while(!glfwWindowShouldClose(win)) { unsigned long long time_bef = get_time(); //((float*)buf_mem)[1] -= 0.00001; glfwPollEvents(); res = vkWaitForFences(dev, 1, &fence_flight, VK_TRUE, UINT64_MAX); res = vkResetFences(dev, 1, &fence_flight); uint32_t img_inx; res = vkAcquireNextImageKHR(dev, swapchain, UINT64_MAX, sem_avail, NULL, &img_inx); res = vkResetCommandBuffer(cmd_buf, 0); { VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, 0, NULL }; res = vkBeginCommandBuffer(cmd_buf, &begin_info); } { VkClearValue clear_vals[2]; clear_vals[0].color = (VkClearColorValue){{0.0f, 0.0f, 0.0f, 1.0f}}; clear_vals[1].depthStencil = (VkClearDepthStencilValue){1.0f, 0}; VkRenderPassBeginInfo begin_pass_info = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, pass, framebuffers[img_inx], {0, 0, 1920, 1080}, 2, &clear_vals[0] }; vkCmdBeginRenderPass(cmd_buf, &begin_pass_info, VK_SUBPASS_CONTENTS_INLINE); } vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout, 0, 1, &desc_sets[0], 0, NULL); if(key_pressed[0]) { pos_y += 0.001; } if(key_pressed[1]) { pos_y -= 0.001; } if(key_pressed[2]) { rot_y += 0.001; } if(key_pressed[3]) { rot_y -= 0.001; } if(key_pressed[8]) { rot_x += 0.001; } if(key_pressed[9]) { rot_x -= 0.001; } if(key_pressed[4]) { pos_x -= -sin(rot_y)*0.001; pos_z -= cos(rot_y)*0.001; } if(key_pressed[5]) { pos_x += -sin(rot_y)*0.001; pos_z += cos(rot_y)*0.001; } if(key_pressed[6]) { pos_x += cos(rot_y)*0.001; pos_z += sin(rot_y)*0.001; } if(key_pressed[7]) { pos_x -= cos(rot_y)*0.001; pos_z -= sin(rot_y)*0.001; } vkCmdPushConstants(cmd_buf, pipe_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, (float[]){ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, rot_x, }); vkCmdPushConstants(cmd_buf, pipe_layout, VK_SHADER_STAGE_VERTEX_BIT, 64, 16, (float[]){ pos_x, pos_y, pos_z, rot_y }); vkCmdPushConstants(cmd_buf, pipe_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 64+16, 16, (float[]){ 0.0, 1.0, 1.0, 1.0, }); vkCmdDraw(cmd_buf, 36, 1, 0, 0); vkCmdEndRenderPass(cmd_buf); { res = vkEndCommandBuffer(cmd_buf); } { VkPipelineStageFlags stage_flags = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO, NULL, 1, &sem_avail, &stage_flags, 1, &cmd_buf, 1, &sem_finish }; res = vkQueueSubmit(queue, 1, &submit_info, fence_flight); } { VkPresentInfoKHR present_info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, NULL, 1, &sem_finish, 1, &swapchain, &img_inx, NULL }; res = vkQueuePresentKHR(queue, &present_info); } unsigned long long time_now = get_time(); //printf("ms per frame: %llu\n", (time_now - time_bef)/1000); } }