#ifndef GPU_H #define GPU_H #define VK_USE_PLATFORM_MACOS_MVK #include "vulkan/vk_enum_string_helper.h" #include "vulkan/vulkan_core.h" #include "vk_mem_alloc.h" #define GLFW_INCLUDE_VULKAN #include #ifdef __APPLE__ #define GLFW_EXPOSE_NATIVE_COCOA #endif #include #define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include #include #include #include #include #include #define MAX_FRAMES_IN_FLIGHT 2 #define WINDOW_MIN_WIDTH 800 #define WINDOW_MIN_HEIGHT 600 #define PERSPECTIVE_FOVY (-M_PI/3) #define PERSPECTIVE_NEARZ 0.01 #define PERSPECTIVE_FARZ 1000 #define VK_RESULT(x) {\ result = x;\ if(result != VK_SUCCESS) {\ fprintf(stderr, "%s:%d %s failed with %s\n", __FILE__, __LINE__, #x, string_VkResult(result));\ return x;\ }\ } typedef struct ComputePipelineStruct { VkPipelineLayout layout; VkPipeline pipeline; } ComputePipeline; typedef struct GraphicsPipelineStruct { VkPipelineLayout layout; VkPipeline pipeline; } GraphicsPipeline; typedef struct DrawCommandStruct { uint32_t vertex_count; uint32_t instance_count; uint32_t first_vertex; uint32_t first_instance; } DrawCommand; typedef struct DispatchCommandStruct { uint32_t x; uint32_t y; uint32_t z; } DispatchCommand; typedef struct GPUQueueStruct { VkQueue handle; uint32_t family; uint32_t index; } GPUQueue; typedef struct SwapchainDetailsStruct { VkSurfaceCapabilitiesKHR capabilities; VkSurfaceFormatKHR* formats; uint32_t formats_count; VkPresentModeKHR* present_modes; uint32_t present_modes_count; } SwapchainDetails; typedef struct TransferInfoStruct { VkDeviceSize offset; VkDeviceSize size; VkBuffer buffer; } TransferInfo; typedef struct TransferBufferStruct { VkBuffer buffer; VmaAllocation memory; void* mapped; size_t written; size_t max_size; size_t max_count; TransferInfo* infos; uint32_t count; } TransferBuffer; typedef struct FrameContextStruct { VkFence ready; VkSemaphore image; VkSemaphore render; VkSemaphore transfer; VkSemaphore compute; uint64_t transfer_index; uint64_t compute_index; VkCommandBuffer compute_commands; VkCommandBuffer transfer_commands; TransferBuffer transfers[2]; } FrameContext; typedef struct RenderContextStruct { VkInstance instance; VkDebugUtilsMessengerEXT debug_messenger; VkPhysicalDevice physical_device; VkSurfaceKHR surface; GPUQueue graphics_queue; GPUQueue present_queue; GPUQueue transfer_queue; VkDevice device; VmaAllocator allocator; SwapchainDetails swapchain_details; VkSurfaceFormatKHR swapchain_format; VkPresentModeKHR swapchain_present_mode; VkExtent2D swapchain_extent; VkSwapchainKHR swapchain; uint32_t swapchain_image_count; VkImage* swapchain_images; VkImageView* swapchain_image_views; VkFramebuffer* swapchain_framebuffers; VkFormat depth_format; VkImageView depth_image_view; VkImage depth_image; VmaAllocation depth_image_memory; VkCommandPool extra_graphics_pool; VkCommandPool graphics_pool; VkCommandPool transfer_pool; VkRenderPass render_pass; VkCommandBuffer* swapchain_command_buffers; uint64_t swapchain_command_buffer_record_id; uint64_t* swapchain_command_buffer_record_ids; FrameContext frame[MAX_FRAMES_IN_FLIGHT]; uint32_t current_frame; vec2 window_scale; bool framebuffer_recreated; } RenderContext; GLFWwindow* init_window(); VkResult init_vulkan( GLFWwindow* window, RenderContext* context); VkResult create_transfer_buffer( VmaAllocator allocator, VkDeviceSize size, VkBuffer* buffer, VmaAllocation* memory, void** mapped); void destroy_transfer_buffer( VmaAllocator allocator, VkBuffer buffer, VmaAllocation memory); VkResult create_storage_buffer( VmaAllocator allocator, VkBufferUsageFlags usage, VkDeviceSize size, VkBuffer* buffer, VmaAllocation* memory); VkDeviceAddress buffer_address( VkDevice device, VkBuffer buffer); VkResult add_transfer( void* data, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, uint32_t frame_index, RenderContext* gpu); VkResult add_transfers( void* data, VkBuffer* buffers, VkDeviceSize offset, VkDeviceSize size, RenderContext* gpu); VkCommandBuffer command_begin_single( VkDevice device, VkCommandPool transfer_pool); VkResult command_end_single( VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, GPUQueue transfer_queue); void command_copy_buffer( VkCommandBuffer command_buffer, VkBuffer src, VkBuffer dst, VkDeviceSize src_offset, VkDeviceSize dst_offset, VkDeviceSize size); VkResult command_transition_image_layout( VkDevice device, VkCommandPool transfer_pool, GPUQueue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags); VkShaderModule load_shader_file( const char* path, VkDevice device); VkResult recreate_framebuffer( RenderContext* gpu); #endif