commit 6fa972cd5606fb792ee52d7638f5be903aaf12cc Author: itycodes Date: Tue Mar 4 15:33:35 2025 +0100 Initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7599e52 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +.PHONY: run clean + +SHADERS = vert.spv frag.spv +CC = gcc +LIBS = -lvulkan -lglfw -lm +CFLAGS = $(LIBS) -g +OUT = main +SRC = main.c + +all: $(SHADERS) $(OUT) + +$(OUT): $(SRC) + $(CC) $(CFLAGS) $(SRC) -o $(OUT) + +run: all + ./$(OUT) + +clean: + rm $(SHADERS) + rm $(OUT) + +%.spv: %.vert + glslc $< -o $@ + +%.spv: %.frag + glslc $< -o $@ diff --git a/README.md b/README.md new file mode 100644 index 0000000..63346bd --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Compiling & Running +Compile: +```sh +make +``` +Run: +```sh +make run +``` + +Do note that [SPIR-V Tools](https://github.com/KhronosGroup/SPIRV-Tools) can be used to +disassemble (`spirv-dis`), modify, and assemble (`spirv-as`) SPIR-V bytecode. diff --git a/frag.frag b/frag.frag new file mode 100644 index 0000000..c44c0bc --- /dev/null +++ b/frag.frag @@ -0,0 +1,9 @@ +#version 450 + +layout(location = 0) out vec4 outColor; + +void main() { + if(1 == 1) { + outColor = vec4(1.0); + } +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..7401e30 --- /dev/null +++ b/main.c @@ -0,0 +1,847 @@ +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include + +#define MESH_SIZE 36*2*4*4 + +int main() { + uint32_t glfw_res = glfwInit(); + printf("glfwInit: (%d)\n", glfw_res); + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + GLFWwindow* win = glfwCreateWindow(1920, 1080, "Hi!", NULL, NULL); + 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, + }; + 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[0]; + } + + { + 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); + + 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 (%016x) %03d: SIZE: %luMiB 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 (%016x) %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); + } + + 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]; + { + VkDescriptorSetLayoutCreateInfo layout_info = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + 0, + NULL + }; + res = vkCreateDescriptorSetLayout(dev, &layout_info, NULL, &set_layouts[0]); + printf("CreateDescriptorSetLayout: (%ld)\n", res); + } + + VkPipelineLayout pipe_layout; + { + VkPushConstantRange push_range[] = {}; + VkPipelineLayoutCreateInfo pipe_layout_info = { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + NULL, + 0, + sizeof(set_layouts)/sizeof(set_layouts[0]), + &set_layouts[0], + 0, + 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 + }; + + 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("CreateGraphicsPipelines: (%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); + } + + 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)) { + //((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); + + vkCmdDraw(cmd_buf, 6, 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); + } + } +} diff --git a/vert.vert b/vert.vert new file mode 100644 index 0000000..0af2050 --- /dev/null +++ b/vert.vert @@ -0,0 +1,16 @@ +#version 450 +// vim: ft=c + +const vec3 verts[] = vec3[]( + vec3(-1., -1., 0.), + vec3( 1., -1., 0.), + vec3(-1., 1., 0.), + + vec3( 1., -1., 0.), + vec3( 1., 1., 0.), + vec3(-1., 1., 0.) +); + +void main() { + gl_Position = vec4(verts[gl_VertexIndex], 1.); +}