|
|
@ -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);
|
|
|
|