First pass of pushing object data as DeviceAddress for entire batch at once

main
noah metz 2024-01-13 15:27:14 -07:00
parent c3d727d444
commit a730ab001b
4 changed files with 112 additions and 65 deletions

@ -41,7 +41,7 @@ typedef struct GPUImageStruct {
GPUMemoryType pick_memory(VkPhysicalDeviceMemoryProperties memories, uint32_t filter, VkMemoryPropertyFlags include, VkMemoryPropertyFlags exclude); 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); void gpu_page_free(VkDevice device, GPUPage* page);
VkResult gpu_buffer_malloc(VkDevice device, GPUPage* page, VkDeviceSize size, VkBufferUsageFlags usage, GPUBuffer* buffer); 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); VkResult gpu_image_malloc(VkDevice device, GPUPage* page, VkImageCreateInfo* info, GPUImage* image);

@ -1,8 +1,18 @@
#version 450 #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 { layout( push_constant ) uniform constants {
mat4 view; mat4 view;
mat4 proj; mat4 proj;
ObjectBuffer objects;
} scene; } scene;
layout(set = 0, binding = 0) uniform SceneUniform { layout(set = 0, binding = 0) uniform SceneUniform {
@ -15,6 +25,6 @@ layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor; layout(location = 0) out vec3 fragColor;
void main() { 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; fragColor = inColor;
} }

@ -25,7 +25,7 @@ GPUMemoryType pick_memory(VkPhysicalDeviceMemoryProperties memories, uint32_t fi
return err; 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) { if(handle == NULL) {
return VK_ERROR_VALIDATION_FAILED_EXT; return VK_ERROR_VALIDATION_FAILED_EXT;
} }
@ -52,11 +52,16 @@ VkResult gpu_page_allocate(VkDevice device, VkPhysicalDeviceMemoryProperties mem
return VK_ERROR_UNKNOWN; return VK_ERROR_UNKNOWN;
} }
VkMemoryAllocateFlagsInfo allocate_flags_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
.flags = allocate_flags,
};
VkMemoryAllocateInfo allocate_info = { VkMemoryAllocateInfo allocate_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = size, .allocationSize = size,
.memoryTypeIndex = memory_type.index, .memoryTypeIndex = memory_type.index,
.pNext = NULL, .pNext = &allocate_flags_info,
}; };
VkDeviceMemory memory = VK_NULL_HANDLE; VkDeviceMemory memory = VK_NULL_HANDLE;

@ -1,5 +1,6 @@
#define VK_USE_PLATFORM_MACOS_MVK #define VK_USE_PLATFORM_MACOS_MVK
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
#include "vulkan/vk_enum_string_helper.h"
#define GLFW_INCLUDE_VULKAN #define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -106,9 +107,6 @@ typedef struct MeshStruct {
} Mesh; } Mesh;
typedef struct GraphicsPipelineInfoStruct { typedef struct GraphicsPipelineInfoStruct {
uint32_t scene_pcr_size;
uint32_t pipeline_pcr_size;
VkDescriptorSetLayout scene_layout; VkDescriptorSetLayout scene_layout;
VkDescriptorSetLayoutBinding* descriptor_bindings; VkDescriptorSetLayoutBinding* descriptor_bindings;
@ -126,15 +124,12 @@ typedef struct GraphicsPipelineInfoStruct {
typedef struct GraphicsPipelineStruct { typedef struct GraphicsPipelineStruct {
uint32_t max_frames_in_flight; uint32_t max_frames_in_flight;
uint32_t max_objects;
VkDescriptorPool descriptor_pool; VkDescriptorPool descriptor_pool;
VkDescriptorSet* descriptors; VkDescriptorSet* descriptors;
VkDescriptorSetLayout descriptors_layout; VkDescriptorSetLayout descriptors_layout;
uint32_t pcr_size;
uint32_t pcr_offset;
void** pcr_ptrs;
VkPipelineLayout layout; VkPipelineLayout layout;
VkPipeline pipeline; VkPipeline pipeline;
} GraphicsPipeline; } GraphicsPipeline;
@ -230,10 +225,6 @@ struct ModelUBO {
mat4 model; mat4 model;
}; };
struct ObjectPC {
mat4 model;
};
struct SceneUBO { struct SceneUBO {
mat4 test; mat4 test;
}; };
@ -279,6 +270,7 @@ uint32_t instance_extension_count = sizeof(instance_extensions) / sizeof(const c
const char * device_extensions[] = { const char * device_extensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
"VK_KHR_portability_subset", "VK_KHR_portability_subset",
}; };
uint32_t device_extension_count = sizeof(device_extensions) / sizeof(const char *); 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; 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 = { VkPhysicalDeviceFeatures device_features = {
.samplerAnisotropy = VK_TRUE, .samplerAnisotropy = VK_TRUE,
}; };
@ -648,6 +650,7 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu
.ppEnabledExtensionNames = device_extensions, .ppEnabledExtensionNames = device_extensions,
.enabledLayerCount = validation_layer_count, .enabledLayerCount = validation_layer_count,
.ppEnabledLayerNames = validation_layers, .ppEnabledLayerNames = validation_layers,
.pNext = &features_12,
}; };
VkResult result = vkCreateDevice(physical_device, &device_create_info, 0, device); 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); 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); 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); 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);
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]);
}
// Bind the scene descriptor
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &scene_descriptors[frame_num], 0, 0); vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &scene_descriptors[frame_num], 0, 0);
if(pipeline.descriptors != NULL) { if(pipeline.descriptors != NULL) {
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 1, 1, &pipeline.descriptors[frame_num], 0, 0); 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++) { for(uint32_t i = 0; i < object_count; i++) {
command_draw_object(objects[i], command_buffer); 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 = { VkCommandBufferBeginInfo begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = 0, .flags = 0,
@ -1470,7 +1473,7 @@ VkResult command_draw_scene(uint32_t pipelines_count, GraphicsPipeline* pipeline
vkCmdSetScissor(command_buffer, 0, 1, &scissor); vkCmdSetScissor(command_buffer, 0, 1, &scissor);
for(uint i = 0; i < pipelines_count; i++) { 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); vkCmdEndRenderPass(command_buffer);
@ -1582,8 +1585,6 @@ VkResult create_graphics_pipeline(
} }
out->max_frames_in_flight = max_frames_in_flight; 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 = { VkDescriptorSetLayoutCreateInfo descriptor_layout_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
@ -1596,29 +1597,8 @@ VkResult create_graphics_pipeline(
return result; 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) { if(pipeline_info.descriptor_bindings_count > 0) {
out->descriptors = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*(1 + pipeline_info.descriptor_bindings_count));
if(out->descriptors == 0) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*pipeline_info.descriptor_bindings_count);
if(pool_sizes == 0) { if(pool_sizes == 0) {
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
} }
@ -1636,6 +1616,7 @@ VkResult create_graphics_pipeline(
.poolSizeCount = pipeline_info.descriptor_bindings_count, .poolSizeCount = pipeline_info.descriptor_bindings_count,
.maxSets = max_frames_in_flight, .maxSets = max_frames_in_flight,
.pPoolSizes = pool_sizes, .pPoolSizes = pool_sizes,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT,
}; };
result = vkCreateDescriptorPool(device, &pool_info, 0, &out->descriptor_pool); result = vkCreateDescriptorPool(device, &pool_info, 0, &out->descriptor_pool);
@ -1644,6 +1625,12 @@ VkResult create_graphics_pipeline(
return result; 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); VkDescriptorSetLayout* set_layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight);
if(set_layouts == 0) { if(set_layouts == 0) {
vkDestroyDescriptorPool(device, out->descriptor_pool, 0); vkDestroyDescriptorPool(device, out->descriptor_pool, 0);
@ -1674,7 +1661,7 @@ VkResult create_graphics_pipeline(
VkPushConstantRange pcr = { VkPushConstantRange pcr = {
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0, .offset = 0,
.size = pipeline_info.scene_pcr_size + pipeline_info.pipeline_pcr_size, .size = sizeof(struct ScenePC) + sizeof(VkDeviceAddress),
}; };
VkPipelineLayoutCreateInfo layout_info = { VkPipelineLayoutCreateInfo layout_info = {
@ -1829,7 +1816,7 @@ VkResult create_graphics_pipeline(
return VK_SUCCESS; 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) { if(out == NULL) {
return VK_ERROR_VALIDATION_FAILED_EXT; 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 = { 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_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo),
.shader_stages = shader_stages, .shader_stages = shader_stages,
.scene_pcr_size = scene_pcr_size,
.scene_layout = scene_layout, .scene_layout = scene_layout,
.input_bindings = bindings, .input_bindings = bindings,
.input_bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), .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), .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); 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) { if(out == NULL) {
return VK_ERROR_VALIDATION_FAILED_EXT; return VK_ERROR_VALIDATION_FAILED_EXT;
} }
@ -1955,7 +1959,6 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRend
GraphicsPipelineInfo pipeline_info = { GraphicsPipelineInfo pipeline_info = {
.shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo),
.shader_stages = shader_stages, .shader_stages = shader_stages,
.scene_pcr_size = scene_pcr_size,
.scene_layout = scene_layout, .scene_layout = scene_layout,
.input_bindings = bindings, .input_bindings = bindings,
.input_bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), .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), .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); 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; 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) { if(result != VK_SUCCESS) {
return 0; return 0;
} }
@ -2349,7 +2358,7 @@ SceneContext create_scene_context(VkDevice device, VkPhysicalDeviceMemoryPropert
} }
GPUPage* scene_ubo_memory = NULL; 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) { if(result != VK_SUCCESS) {
return ret; return ret;
} }
@ -2633,7 +2642,7 @@ struct ScenePC get_scene_constants(vec3 world_position, versor world_rotation, f
return constants; 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); 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; VkResult result;
@ -2658,7 +2667,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi
return result; 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) { if(result != VK_SUCCESS) {
return result; return result;
} }
@ -2697,13 +2706,13 @@ Object create_simple_mesh_object(PlyMesh ply_mesh, GraphicsPipeline* simple_mesh
Object zero = {}; Object zero = {};
GPUPage* mesh_memory = NULL; 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) { if(result != VK_SUCCESS) {
return zero; return zero;
} }
GPUPage* transfer_memory = NULL; 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) { if(result != VK_SUCCESS) {
return zero; return zero;
} }
@ -2757,13 +2766,13 @@ Object create_texture_mesh_object(GraphicsPipeline* texture_mesh_pipeline, VkPhy
Object zero = {}; Object zero = {};
GPUPage* mesh_memory = NULL; 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) { if(result != VK_SUCCESS) {
return zero; return zero;
} }
GPUPage* transfer_memory = NULL; 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) { if(result != VK_SUCCESS) {
return zero; return zero;
} }
@ -2869,9 +2878,9 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
GraphicsPipeline simple_mesh_pipeline = {0}; GraphicsPipeline simple_mesh_pipeline = {0};
GraphicsPipeline texture_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) { 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; return;
} }
@ -2881,7 +2890,7 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
return; 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) { if(result != VK_SUCCESS) {
fprintf(stderr, "failed to create texture mesh material\n"); fprintf(stderr, "failed to create texture mesh material\n");
return; return;
@ -2897,11 +2906,34 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
GraphicsPipeline pipelines[] = {simple_mesh_pipeline, texture_mesh_pipeline}; GraphicsPipeline pipelines[] = {simple_mesh_pipeline, texture_mesh_pipeline};
uint32_t objects_counts[] = {1, 1}; 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; context->current_frame = 0;
while(!glfwWindowShouldClose(window)) { while(!glfwWindowShouldClose(window)) {
glfwPollEvents(); 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) { if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
vkDeviceWaitIdle(context->device); vkDeviceWaitIdle(context->device);
recreate_swapchain(context); recreate_swapchain(context);