From a730ab001bf211339b363805917fed192e5d7bcd Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Sat, 13 Jan 2024 15:27:14 -0700 Subject: [PATCH] First pass of pushing object data as DeviceAddress for entire batch at once --- include/gpu_mem.h | 2 +- shader_src/basic.vert | 12 +++- src/gpu_mem.c | 9 ++- src/main.c | 154 +++++++++++++++++++++++++----------------- 4 files changed, 112 insertions(+), 65 deletions(-) diff --git a/include/gpu_mem.h b/include/gpu_mem.h index aa05f2c..2ba67eb 100644 --- a/include/gpu_mem.h +++ b/include/gpu_mem.h @@ -41,7 +41,7 @@ typedef struct GPUImageStruct { GPUMemoryType pick_memory(VkPhysicalDeviceMemoryProperties memories, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude); -VkResult gpu_page_allocate(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkDeviceSize size, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude, GPUPage** handle); +VkResult gpu_page_allocate(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkDeviceSize size, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude, VkMemoryAllocateFlags allocate_flags, GPUPage** handle); void gpu_page_free(VkDevice device, GPUPage* page); VkResult gpu_buffer_malloc(VkDevice device, GPUPage* page, VkDeviceSize size, VkBufferUsageFlags usage, GPUBuffer* buffer); VkResult gpu_image_malloc(VkDevice device, GPUPage* page, VkImageCreateInfo* info, GPUImage* image); diff --git a/shader_src/basic.vert b/shader_src/basic.vert index 4b796d0..b9c5726 100644 --- a/shader_src/basic.vert +++ b/shader_src/basic.vert @@ -1,8 +1,18 @@ #version 450 +#extension GL_EXT_buffer_reference : require + +struct Object { + mat4 model; +}; + +layout(buffer_reference, buffer_reference_align = 16) buffer ObjectBuffer { + Object objects[]; +}; layout( push_constant ) uniform constants { mat4 view; mat4 proj; + ObjectBuffer objects; } scene; layout(set = 0, binding = 0) uniform SceneUniform { @@ -15,6 +25,6 @@ layout(location = 1) in vec3 inColor; layout(location = 0) out vec3 fragColor; void main() { - gl_Position = scene.proj * scene.view * vec4(inPosition, 1.0); + gl_Position = scene.proj * scene.view * scene.objects.objects[0].model * vec4(inPosition, 1.0); fragColor = inColor; } diff --git a/src/gpu_mem.c b/src/gpu_mem.c index 087aaf6..55e0769 100644 --- a/src/gpu_mem.c +++ b/src/gpu_mem.c @@ -25,7 +25,7 @@ GPUMemoryType pick_memory(VkPhysicalDeviceMemoryProperties memories, uint32_t fi return err; } -VkResult gpu_page_allocate(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkDeviceSize size, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude, GPUPage** handle) { +VkResult gpu_page_allocate(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkDeviceSize size, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude, VkMemoryAllocateFlags allocate_flags, GPUPage** handle) { if(handle == NULL) { return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -52,11 +52,16 @@ VkResult gpu_page_allocate(VkDevice device, VkPhysicalDeviceMemoryProperties mem return VK_ERROR_UNKNOWN; } + VkMemoryAllocateFlagsInfo allocate_flags_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, + .flags = allocate_flags, + }; + VkMemoryAllocateInfo allocate_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = size, .memoryTypeIndex = memory_type.index, - .pNext = NULL, + .pNext = &allocate_flags_info, }; VkDeviceMemory memory = VK_NULL_HANDLE; diff --git a/src/main.c b/src/main.c index 2f5d43d..f7a2f51 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #define VK_USE_PLATFORM_MACOS_MVK #include "vulkan/vulkan_core.h" +#include "vulkan/vk_enum_string_helper.h" #define GLFW_INCLUDE_VULKAN #include @@ -106,9 +107,6 @@ typedef struct MeshStruct { } Mesh; typedef struct GraphicsPipelineInfoStruct { - uint32_t scene_pcr_size; - uint32_t pipeline_pcr_size; - VkDescriptorSetLayout scene_layout; VkDescriptorSetLayoutBinding* descriptor_bindings; @@ -126,15 +124,12 @@ typedef struct GraphicsPipelineInfoStruct { typedef struct GraphicsPipelineStruct { uint32_t max_frames_in_flight; + uint32_t max_objects; VkDescriptorPool descriptor_pool; VkDescriptorSet* descriptors; VkDescriptorSetLayout descriptors_layout; - uint32_t pcr_size; - uint32_t pcr_offset; - void** pcr_ptrs; - VkPipelineLayout layout; VkPipeline pipeline; } GraphicsPipeline; @@ -230,10 +225,6 @@ struct ModelUBO { mat4 model; }; -struct ObjectPC { - mat4 model; -}; - struct SceneUBO { mat4 test; }; @@ -279,6 +270,7 @@ uint32_t instance_extension_count = sizeof(instance_extensions) / sizeof(const c const char * device_extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, "VK_KHR_portability_subset", }; uint32_t device_extension_count = sizeof(device_extensions) / sizeof(const char *); @@ -635,6 +627,16 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu queue_create_info[i].pQueuePriorities = &default_queue_priority; } + VkPhysicalDeviceVulkan12Features features_12 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + .bufferDeviceAddress = VK_TRUE, + .descriptorIndexing = VK_TRUE, + .descriptorBindingPartiallyBound = VK_TRUE, + .descriptorBindingVariableDescriptorCount = VK_TRUE, + .descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, + }; + VkPhysicalDeviceFeatures device_features = { .samplerAnisotropy = VK_TRUE, }; @@ -648,6 +650,7 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu .ppEnabledExtensionNames = device_extensions, .enabledLayerCount = validation_layer_count, .ppEnabledLayerNames = validation_layers, + .pNext = &features_12, }; VkResult result = vkCreateDevice(physical_device, &device_create_info, 0, device); @@ -1393,24 +1396,24 @@ void command_draw_object(Object object, VkCommandBuffer command_buffer) { vkCmdDrawIndexed(command_buffer, mesh->index_count, 1, 0, 0, 0); } -void command_draw_pipeline(GraphicsPipeline pipeline, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer) { +void command_draw_pipeline(GraphicsPipeline pipeline, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkDeviceAddress object_buffer_addr, VkCommandBuffer command_buffer) { vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline); - vkCmdPushConstants(command_buffer, pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, pipeline.pcr_offset, scene_constants); - - if(pipeline.pcr_ptrs != NULL && pipeline.pcr_size > 0) { - vkCmdPushConstants(command_buffer, pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, pipeline.pcr_offset, pipeline.pcr_size, pipeline.pcr_ptrs[frame_num]); - } + vkCmdPushConstants(command_buffer, pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(struct ScenePC), scene_constants); + vkCmdPushConstants(command_buffer, pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(struct ScenePC), sizeof(VkDeviceAddress), &object_buffer_addr); + // Bind the scene descriptor vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &scene_descriptors[frame_num], 0, 0); + if(pipeline.descriptors != NULL) { vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 1, 1, &pipeline.descriptors[frame_num], 0, 0); } + for(uint32_t i = 0; i < object_count; i++) { command_draw_object(objects[i], command_buffer); } } -VkResult command_draw_scene(uint32_t pipelines_count, GraphicsPipeline* pipelines, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { +VkResult command_draw_scene(uint32_t pipelines_count, GraphicsPipeline* pipelines, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent, VkDeviceAddress object_buffer_addr) { VkCommandBufferBeginInfo begin_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = 0, @@ -1470,7 +1473,7 @@ VkResult command_draw_scene(uint32_t pipelines_count, GraphicsPipeline* pipeline vkCmdSetScissor(command_buffer, 0, 1, &scissor); for(uint i = 0; i < pipelines_count; i++) { - command_draw_pipeline(pipelines[i], object_counts[i], objects[i], frame_num, scene_descriptors, scene_constants, command_buffer); + command_draw_pipeline(pipelines[i], object_counts[i], objects[i], frame_num, scene_descriptors, scene_constants, object_buffer_addr, command_buffer); } vkCmdEndRenderPass(command_buffer); @@ -1582,8 +1585,6 @@ VkResult create_graphics_pipeline( } out->max_frames_in_flight = max_frames_in_flight; - out->pcr_size = pipeline_info.pipeline_pcr_size; - out->pcr_offset = pipeline_info.scene_pcr_size; VkDescriptorSetLayoutCreateInfo descriptor_layout_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, @@ -1596,29 +1597,8 @@ VkResult create_graphics_pipeline( return result; } - if(pipeline_info.pipeline_pcr_size > 0) { - out->pcr_ptrs = malloc(sizeof(void**)*max_frames_in_flight); - if(out->pcr_ptrs == NULL) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - out->pcr_ptrs[i] = malloc(pipeline_info.pipeline_pcr_size); - if(out->pcr_ptrs[i] == NULL) { - for(uint32_t j = 0; j < i; j++) { - free(out->pcr_ptrs[j]); - } - free(out->pcr_ptrs); - } - } - } - if(pipeline_info.descriptor_bindings_count > 0) { - out->descriptors = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); - if(out->descriptors == 0) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*pipeline_info.descriptor_bindings_count); + VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*(1 + pipeline_info.descriptor_bindings_count)); if(pool_sizes == 0) { return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -1626,7 +1606,7 @@ VkResult create_graphics_pipeline( for(uint32_t i = 0; i < pipeline_info.descriptor_bindings_count; i++) { VkDescriptorPoolSize pool_size = { .type = pipeline_info.descriptor_bindings[i].descriptorType, - .descriptorCount = pipeline_info.descriptor_bindings[i].descriptorCount * max_frames_in_flight, + .descriptorCount = pipeline_info.descriptor_bindings[i].descriptorCount*max_frames_in_flight, }; pool_sizes[i] = pool_size; } @@ -1636,6 +1616,7 @@ VkResult create_graphics_pipeline( .poolSizeCount = pipeline_info.descriptor_bindings_count, .maxSets = max_frames_in_flight, .pPoolSizes = pool_sizes, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT, }; result = vkCreateDescriptorPool(device, &pool_info, 0, &out->descriptor_pool); @@ -1644,6 +1625,12 @@ VkResult create_graphics_pipeline( return result; } + out->descriptors = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); + if(out->descriptors == 0) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + VkDescriptorSetLayout* set_layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); if(set_layouts == 0) { vkDestroyDescriptorPool(device, out->descriptor_pool, 0); @@ -1674,7 +1661,7 @@ VkResult create_graphics_pipeline( VkPushConstantRange pcr = { .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .offset = 0, - .size = pipeline_info.scene_pcr_size + pipeline_info.pipeline_pcr_size, + .size = sizeof(struct ScenePC) + sizeof(VkDeviceAddress), }; VkPipelineLayoutCreateInfo layout_info = { @@ -1829,7 +1816,7 @@ VkResult create_graphics_pipeline( return VK_SUCCESS; } -VkResult create_simple_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t scene_pcr_size, uint32_t max_frames_in_flight, GraphicsPipeline* out) { +VkResult create_simple_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, GraphicsPipeline* out) { if(out == NULL) { return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1874,10 +1861,21 @@ VkResult create_simple_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRende }, }; + VkDescriptorSetLayoutBinding descriptor_bindings[] = { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .pImmutableSamplers = 0, + }, + }; + GraphicsPipelineInfo pipeline_info = { + .descriptor_bindings_count = sizeof(descriptor_bindings)/sizeof(VkDescriptorSetLayoutBinding), + .descriptor_bindings = descriptor_bindings, .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), .shader_stages = shader_stages, - .scene_pcr_size = scene_pcr_size, .scene_layout = scene_layout, .input_bindings = bindings, .input_bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), @@ -1885,10 +1883,16 @@ VkResult create_simple_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRende .input_attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), }; + GPUPage* memory = NULL; + VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &memory); + if(result != VK_SUCCESS) { + return result; + } + return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out); } -VkResult create_texture_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t scene_pcr_size, uint32_t max_frames_in_flight, GraphicsPipeline* out) { +VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, GraphicsPipeline* out) { if(out == NULL) { return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1955,7 +1959,6 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRend GraphicsPipelineInfo pipeline_info = { .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), .shader_stages = shader_stages, - .scene_pcr_size = scene_pcr_size, .scene_layout = scene_layout, .input_bindings = bindings, .input_bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), @@ -1963,6 +1966,12 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRend .input_attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), }; + GPUPage* memory = NULL; + VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &memory); + if(result != VK_SUCCESS) { + return result; + } + return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out); } @@ -2214,7 +2223,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->in_flight_fences = if_fences; } - result = gpu_page_allocate(context->device, context->memories, 15360000*3, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &context->g_buffer_page); + result = gpu_page_allocate(context->device, context->memories, 15360000*3, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0, &context->g_buffer_page); if(result != VK_SUCCESS) { return 0; } @@ -2349,7 +2358,7 @@ SceneContext create_scene_context(VkDevice device, VkPhysicalDeviceMemoryPropert } GPUPage* scene_ubo_memory = NULL; - result = gpu_page_allocate(device, memories, 1000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &scene_ubo_memory); + result = gpu_page_allocate(device, memories, 1000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &scene_ubo_memory); if(result != VK_SUCCESS) { return ret; } @@ -2633,7 +2642,7 @@ struct ScenePC get_scene_constants(vec3 world_position, versor world_rotation, f return constants; } -VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, GraphicsPipeline* pipelines, uint32_t* objects_counts, Object** objects) { +VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, GraphicsPipeline* pipelines, uint32_t* objects_counts, Object** objects, VkDeviceAddress object_buffer_addr) { struct ScenePC scene_constants = get_scene_constants(world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01); VkResult result; @@ -2658,7 +2667,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi return result; } - result = command_draw_scene(materials_count, pipelines, objects_counts, objects, context->current_frame, scene->descriptors, &scene_constants, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); + result = command_draw_scene(materials_count, pipelines, objects_counts, objects, context->current_frame, scene->descriptors, &scene_constants, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent, object_buffer_addr); if(result != VK_SUCCESS) { return result; } @@ -2697,13 +2706,13 @@ Object create_simple_mesh_object(PlyMesh ply_mesh, GraphicsPipeline* simple_mesh Object zero = {}; GPUPage* mesh_memory = NULL; - VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &mesh_memory); + VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0, &mesh_memory); if(result != VK_SUCCESS) { return zero; } GPUPage* transfer_memory = NULL; - result = gpu_page_allocate(device, memories, 200000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &transfer_memory); + result = gpu_page_allocate(device, memories, 200000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &transfer_memory); if(result != VK_SUCCESS) { return zero; } @@ -2757,13 +2766,13 @@ Object create_texture_mesh_object(GraphicsPipeline* texture_mesh_pipeline, VkPhy Object zero = {}; GPUPage* mesh_memory = NULL; - VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &mesh_memory); + VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0, &mesh_memory); if(result != VK_SUCCESS) { return zero; } GPUPage* transfer_memory = NULL; - result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &transfer_memory); + result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &transfer_memory); if(result != VK_SUCCESS) { return zero; } @@ -2869,9 +2878,9 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) { GraphicsPipeline simple_mesh_pipeline = {0}; GraphicsPipeline texture_mesh_pipeline = {0}; - VkResult result = create_simple_mesh_pipeline(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr_size, context->max_frames_in_flight, &simple_mesh_pipeline); + VkResult result = create_simple_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight, &simple_mesh_pipeline); if(result != VK_SUCCESS) { - fprintf(stderr, "failed to create simple mesh material\n"); + fprintf(stderr, "failed to create simple mesh material: %s\n", string_VkResult(result)); return; } @@ -2881,7 +2890,7 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) { return; } - result = create_texture_mesh_pipeline(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr_size, context->max_frames_in_flight, &texture_mesh_pipeline); + result = create_texture_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight, &texture_mesh_pipeline); if(result != VK_SUCCESS) { fprintf(stderr, "failed to create texture mesh material\n"); return; @@ -2897,11 +2906,34 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) { GraphicsPipeline pipelines[] = {simple_mesh_pipeline, texture_mesh_pipeline}; uint32_t objects_counts[] = {1, 1}; + GPUPage* memory = NULL; + result = gpu_page_allocate(context->device, context->memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, &memory); + if(result != VK_SUCCESS) { + return; + } + + GPUBuffer buffer = {0}; + result = gpu_buffer_malloc(context->device, memory, sizeof(mat4)*100, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, &buffer); + if(result != VK_SUCCESS) { + return; + } + + mat4* tmp = memory->ptr + buffer.memory->offset; + glm_mat4_identity(*tmp); + vec3 scale = {2.0f, 2.0f, 2.0f}; + glm_scale(*tmp, scale); + + VkBufferDeviceAddressInfo addr_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + .buffer = buffer.handle, + }; + VkDeviceAddress object_address = vkGetBufferDeviceAddress(context->device, &addr_info); + context->current_frame = 0; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); - VkResult result = draw_frame(context, &scene, sizeof(pipelines)/sizeof(GraphicsPipeline), pipelines, objects_counts, objects); + VkResult result = draw_frame(context, &scene, sizeof(pipelines)/sizeof(GraphicsPipeline), pipelines, objects_counts, objects, object_address); if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { vkDeviceWaitIdle(context->device); recreate_swapchain(context);