|
|
@ -51,20 +51,8 @@ typedef struct AllocatedBufferStruct {
|
|
|
|
} AllocatedBuffer;
|
|
|
|
} AllocatedBuffer;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct MaterialStruct {
|
|
|
|
typedef struct MaterialStruct {
|
|
|
|
uint32_t descriptor_set_layouts_count;
|
|
|
|
|
|
|
|
VkDescriptorSetLayout* descriptor_set_layouts;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t push_constant_ranges_count;
|
|
|
|
|
|
|
|
VkPushConstantRange* push_constant_ranges;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkPipelineLayout pipeline_layout;
|
|
|
|
VkPipelineLayout pipeline_layout;
|
|
|
|
VkPipeline pipeline;
|
|
|
|
VkPipeline pipeline;
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorPool descriptor_pool;
|
|
|
|
|
|
|
|
uint32_t frame_count;
|
|
|
|
|
|
|
|
VkDescriptorSet* descriptor_sets;
|
|
|
|
|
|
|
|
AllocatedBuffer* uniform_buffers;
|
|
|
|
|
|
|
|
void** uniform_buffer_ptrs;
|
|
|
|
|
|
|
|
} Material;
|
|
|
|
} Material;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct MeshStruct {
|
|
|
|
typedef struct MeshStruct {
|
|
|
@ -110,6 +98,12 @@ typedef struct VulkanContextStruct {
|
|
|
|
VkCommandPool graphics_command_pool;
|
|
|
|
VkCommandPool graphics_command_pool;
|
|
|
|
VkCommandPool transfer_command_pool;
|
|
|
|
VkCommandPool transfer_command_pool;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorPool scene_ubo_pool;
|
|
|
|
|
|
|
|
VkDescriptorSetLayout scene_ubo_layout;
|
|
|
|
|
|
|
|
VkDescriptorSet* scene_ubo_descriptors;
|
|
|
|
|
|
|
|
AllocatedBuffer* scene_ubos;
|
|
|
|
|
|
|
|
void** scene_ubo_ptrs;
|
|
|
|
|
|
|
|
|
|
|
|
Mesh triangle_mesh;
|
|
|
|
Mesh triangle_mesh;
|
|
|
|
Material simple_mesh_material;
|
|
|
|
Material simple_mesh_material;
|
|
|
|
|
|
|
|
|
|
|
@ -121,8 +115,7 @@ struct Vertex{
|
|
|
|
vec3 color;
|
|
|
|
vec3 color;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct ShaderUBO {
|
|
|
|
struct SceneUBO {
|
|
|
|
mat4 model;
|
|
|
|
|
|
|
|
mat4 view;
|
|
|
|
mat4 view;
|
|
|
|
mat4 proj;
|
|
|
|
mat4 proj;
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -441,9 +434,9 @@ VkDebugUtilsMessengerEXT create_debug_messenger(VkInstance instance) {
|
|
|
|
return debug_messenger;
|
|
|
|
return debug_messenger;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorPool create_descriptor_pool(VkDevice device, uint32_t size) {
|
|
|
|
VkDescriptorPool create_descriptor_pool(VkDevice device, VkDescriptorType type, uint32_t size) {
|
|
|
|
VkDescriptorPoolSize pool_size = {};
|
|
|
|
VkDescriptorPoolSize pool_size = {};
|
|
|
|
pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
|
|
pool_size.type = type;
|
|
|
|
pool_size.descriptorCount = size;
|
|
|
|
pool_size.descriptorCount = size;
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorPoolCreateInfo pool_info = {};
|
|
|
|
VkDescriptorPoolCreateInfo pool_info = {};
|
|
|
@ -1062,21 +1055,7 @@ AllocatedBuffer create_populated_buffer(VkPhysicalDevice physical_device, VkDevi
|
|
|
|
return vertex_buffer;
|
|
|
|
return vertex_buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkPipeline create_graphics_pipeline(VkDevice device, VkExtent2D extent, VkPipelineLayout layout, VkRenderPass render_pass) {
|
|
|
|
VkPipeline create_graphics_pipeline(VkDevice device, VkExtent2D extent, VkPipelineLayout layout, VkRenderPass render_pass, uint32_t shader_stage_count, VkPipelineShaderStageCreateInfo* shader_stages) {
|
|
|
|
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/basic.vert.spv", device);
|
|
|
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/basic.frag.spv", device);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
|
|
|
|
|
|
|
shader_stages[0].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
|
|
|
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
|
|
|
|
shader_stages[0].module = vert_shader;
|
|
|
|
|
|
|
|
shader_stages[0].pName = "main";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shader_stages[1].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
|
|
|
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
|
|
|
|
shader_stages[1].module = frag_shader;
|
|
|
|
|
|
|
|
shader_stages[1].pName = "main";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDynamicState dynamic_states[] = {
|
|
|
|
VkDynamicState dynamic_states[] = {
|
|
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
|
|
VK_DYNAMIC_STATE_SCISSOR,
|
|
|
|
VK_DYNAMIC_STATE_SCISSOR,
|
|
|
@ -1165,7 +1144,7 @@ VkPipeline create_graphics_pipeline(VkDevice device, VkExtent2D extent, VkPipeli
|
|
|
|
|
|
|
|
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_info = {};
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_info = {};
|
|
|
|
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
|
|
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
|
|
pipeline_info.stageCount = 2;
|
|
|
|
pipeline_info.stageCount = shader_stage_count;
|
|
|
|
pipeline_info.pStages = shader_stages;
|
|
|
|
pipeline_info.pStages = shader_stages;
|
|
|
|
pipeline_info.pVertexInputState = &vertex_input_info;
|
|
|
|
pipeline_info.pVertexInputState = &vertex_input_info;
|
|
|
|
pipeline_info.pInputAssemblyState = &input_assemvly_info;
|
|
|
|
pipeline_info.pInputAssemblyState = &input_assemvly_info;
|
|
|
@ -1205,7 +1184,26 @@ VkCommandPool create_command_pool(VkDevice device, uint32_t queue_family) {
|
|
|
|
return command_pool;
|
|
|
|
return command_pool;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult record_command_buffer_mesh(VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent, Material material, Mesh mesh, uint32_t current_frame) {
|
|
|
|
void record_command_buffer_mesh(Mesh mesh, VkCommandBuffer command_buffer) {
|
|
|
|
|
|
|
|
VkBuffer vertex_buffers[] = {mesh.vertex_buffer.buffer};
|
|
|
|
|
|
|
|
VkDeviceSize offsets[] = {0};
|
|
|
|
|
|
|
|
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets);
|
|
|
|
|
|
|
|
vkCmdBindIndexBuffer(command_buffer, mesh.index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vkCmdDrawIndexed(command_buffer, mesh.index_count, 1, 0, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void record_command_buffer_material(Material material, uint32_t mesh_count, Mesh* meshes, VkDescriptorSet scene_ubo_descriptor, VkCommandBuffer command_buffer) {
|
|
|
|
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline);
|
|
|
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline_layout, 0, 1, &scene_ubo_descriptor, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < mesh_count; i++) {
|
|
|
|
|
|
|
|
record_command_buffer_mesh(meshes[i], command_buffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkResult record_command_buffer_scene(uint32_t materials_count, Material* materials, uint32_t* mesh_counts, Mesh** meshes, VkDescriptorSet scene_ubo_descriptor, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) {
|
|
|
|
VkCommandBufferBeginInfo begin_info = {};
|
|
|
|
VkCommandBufferBeginInfo begin_info = {};
|
|
|
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
|
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
|
|
begin_info.flags = 0;
|
|
|
|
begin_info.flags = 0;
|
|
|
@ -1228,12 +1226,6 @@ VkResult record_command_buffer_mesh(VkCommandBuffer command_buffer, VkRenderPass
|
|
|
|
render_pass_info.pClearValues = &clear_color;
|
|
|
|
render_pass_info.pClearValues = &clear_color;
|
|
|
|
|
|
|
|
|
|
|
|
vkCmdBeginRenderPass(command_buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
vkCmdBeginRenderPass(command_buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkBuffer vertex_buffers[] = {mesh.vertex_buffer.buffer};
|
|
|
|
|
|
|
|
VkDeviceSize offsets[] = {0};
|
|
|
|
|
|
|
|
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets);
|
|
|
|
|
|
|
|
vkCmdBindIndexBuffer(command_buffer, mesh.index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkViewport viewport = {};
|
|
|
|
VkViewport viewport = {};
|
|
|
|
viewport.x = 0.0f;
|
|
|
|
viewport.x = 0.0f;
|
|
|
@ -1250,8 +1242,10 @@ VkResult record_command_buffer_mesh(VkCommandBuffer command_buffer, VkRenderPass
|
|
|
|
scissor.extent = extent;
|
|
|
|
scissor.extent = extent;
|
|
|
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
|
|
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
|
|
|
|
|
|
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline_layout, 0, 1, &material.descriptor_sets[current_frame], 0, 0);
|
|
|
|
for(uint i = 0; i < materials_count; i++) {
|
|
|
|
vkCmdDrawIndexed(command_buffer, mesh.index_count, 1, 0, 0, 0);
|
|
|
|
record_command_buffer_material(materials[i], mesh_counts[i], meshes[i], scene_ubo_descriptor, command_buffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vkCmdEndRenderPass(command_buffer);
|
|
|
|
vkCmdEndRenderPass(command_buffer);
|
|
|
|
|
|
|
|
|
|
|
|
return vkEndCommandBuffer(command_buffer);
|
|
|
|
return vkEndCommandBuffer(command_buffer);
|
|
|
@ -1346,106 +1340,48 @@ Mesh load_mesh(VkPhysicalDevice physical_device, VkDevice device, struct Vertex*
|
|
|
|
return mesh;
|
|
|
|
return mesh;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Material create_simple_mesh_material(VkPhysicalDevice physical_device, VkDevice device, VkExtent2D extent, VkRenderPass render_pass, uint32_t num_frames) {
|
|
|
|
Material create_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, uint32_t shader_stage_count, VkPipelineShaderStageCreateInfo* shader_stages, VkDescriptorSetLayout scene_ubo_layout, uint32_t set_count, VkDescriptorSetLayout* set_layouts, uint32_t pcr_count, VkPushConstantRange* pcrs) {
|
|
|
|
Material zero_material = {
|
|
|
|
Material zero_material = {
|
|
|
|
.pipeline = VK_NULL_HANDLE,
|
|
|
|
.pipeline = VK_NULL_HANDLE,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
AllocatedBuffer* uniform_buffers = allocate_buffers(physical_device, device, sizeof(struct ShaderUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, num_frames);
|
|
|
|
VkDescriptorSetLayout* all_layouts = malloc(sizeof(VkDescriptorSetLayout)*(1+set_count));
|
|
|
|
if(uniform_buffers == 0) {
|
|
|
|
if(all_layouts == 0) {
|
|
|
|
return zero_material;
|
|
|
|
return zero_material;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void** uniform_buffer_ptrs = malloc(sizeof(void*)*num_frames);
|
|
|
|
all_layouts[0] = scene_ubo_layout;
|
|
|
|
if(uniform_buffer_ptrs == 0) {
|
|
|
|
for(uint32_t i = 0; i < set_count; i++) {
|
|
|
|
free(uniform_buffers);
|
|
|
|
all_layouts[i+1] = set_layouts[i];
|
|
|
|
return zero_material;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < num_frames; i++) {
|
|
|
|
|
|
|
|
VkResult result = vkMapMemory(device, uniform_buffers[i].memory, 0, sizeof(struct ShaderUBO), 0, &uniform_buffer_ptrs[i]);
|
|
|
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
|
|
|
for(uint32_t j = 0; j < i; j++) {
|
|
|
|
|
|
|
|
vkUnmapMemory(device, uniform_buffers[j].memory);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
free(uniform_buffers);
|
|
|
|
|
|
|
|
free(uniform_buffer_ptrs);
|
|
|
|
|
|
|
|
return zero_material;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorPool descriptor_pool = create_descriptor_pool(device, num_frames);
|
|
|
|
|
|
|
|
if(descriptor_pool == VK_NULL_HANDLE) {
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < num_frames; i++) {
|
|
|
|
|
|
|
|
vkUnmapMemory(device, uniform_buffers[i].memory);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
free(uniform_buffers);
|
|
|
|
|
|
|
|
free(uniform_buffer_ptrs);
|
|
|
|
|
|
|
|
return zero_material;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutBinding ubo_layout_binding = {
|
|
|
|
VkPushConstantRange* all_pcrs = malloc(sizeof(VkPushConstantRange)*(0+pcr_count));
|
|
|
|
.binding = 0,
|
|
|
|
if((all_pcrs == 0) && (pcr_count != 0)) {
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
free(all_layouts);
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
|
|
|
.pImmutableSamplers = 0,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayout descriptor_set_layout = create_descriptor_set_layout(device, &ubo_layout_binding, 1);
|
|
|
|
|
|
|
|
if(descriptor_set_layout == VK_NULL_HANDLE) {
|
|
|
|
|
|
|
|
return zero_material;
|
|
|
|
return zero_material;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorSet* descriptor_sets = create_descriptor_sets(device, descriptor_set_layout, descriptor_pool, num_frames);
|
|
|
|
for(uint32_t i = 0; i < pcr_count; i++) {
|
|
|
|
if(descriptor_sets == 0) {
|
|
|
|
all_pcrs[i] = pcrs[i];
|
|
|
|
return zero_material;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < num_frames; i++) {
|
|
|
|
VkPipelineLayout pipeline_layout = create_pipeline_layout(device, 1+set_count, all_layouts, 0+pcr_count, all_pcrs);
|
|
|
|
VkDescriptorBufferInfo buffer_info = {};
|
|
|
|
|
|
|
|
buffer_info.buffer = uniform_buffers[i].buffer;
|
|
|
|
|
|
|
|
buffer_info.offset = 0;
|
|
|
|
|
|
|
|
buffer_info.range = sizeof(struct ShaderUBO);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkWriteDescriptorSet descriptor_write = {};
|
|
|
|
|
|
|
|
descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
|
|
|
|
|
descriptor_write.dstSet = descriptor_sets[i];
|
|
|
|
|
|
|
|
descriptor_write.dstBinding = 0;
|
|
|
|
|
|
|
|
descriptor_write.dstArrayElement = 0;
|
|
|
|
|
|
|
|
descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
|
|
|
|
|
|
descriptor_write.descriptorCount = 1;
|
|
|
|
|
|
|
|
descriptor_write.pBufferInfo = &buffer_info;
|
|
|
|
|
|
|
|
descriptor_write.pImageInfo = 0;
|
|
|
|
|
|
|
|
descriptor_write.pTexelBufferView = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkPipelineLayout pipeline_layout = create_pipeline_layout(device, 1, &descriptor_set_layout, 0, 0);
|
|
|
|
|
|
|
|
if(pipeline_layout == VK_NULL_HANDLE) {
|
|
|
|
if(pipeline_layout == VK_NULL_HANDLE) {
|
|
|
|
|
|
|
|
free(all_layouts);
|
|
|
|
|
|
|
|
free(all_pcrs);
|
|
|
|
return zero_material;
|
|
|
|
return zero_material;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(all_layouts);
|
|
|
|
|
|
|
|
free(all_pcrs);
|
|
|
|
|
|
|
|
|
|
|
|
VkPipeline pipeline = create_graphics_pipeline(device, extent, pipeline_layout, render_pass);
|
|
|
|
VkPipeline pipeline = create_graphics_pipeline(device, extent, pipeline_layout, render_pass, shader_stage_count, shader_stages);
|
|
|
|
if(pipeline == VK_NULL_HANDLE) {
|
|
|
|
if(pipeline == VK_NULL_HANDLE) {
|
|
|
|
return zero_material;
|
|
|
|
return zero_material;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Material material = {
|
|
|
|
Material material = {
|
|
|
|
.descriptor_set_layouts_count = 1,
|
|
|
|
|
|
|
|
.descriptor_set_layouts = &descriptor_set_layout,
|
|
|
|
|
|
|
|
.push_constant_ranges_count = 0,
|
|
|
|
|
|
|
|
.push_constant_ranges = 0,
|
|
|
|
|
|
|
|
.pipeline_layout = pipeline_layout,
|
|
|
|
.pipeline_layout = pipeline_layout,
|
|
|
|
.pipeline = pipeline,
|
|
|
|
.pipeline = pipeline,
|
|
|
|
.descriptor_pool = descriptor_pool,
|
|
|
|
|
|
|
|
.frame_count = num_frames,
|
|
|
|
|
|
|
|
.descriptor_sets = descriptor_sets,
|
|
|
|
|
|
|
|
.uniform_buffers = uniform_buffers,
|
|
|
|
|
|
|
|
.uniform_buffer_ptrs = uniform_buffer_ptrs,
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return material;
|
|
|
|
return material;
|
|
|
@ -1608,7 +1544,99 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
context->in_flight_fences = if_fences;
|
|
|
|
context->in_flight_fences = if_fences;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Material simple_mesh_material = create_simple_mesh_material(context->physical_device, context->device, context->swapchain_extent, context->render_pass, max_frames_in_flight);
|
|
|
|
VkDescriptorPool scene_ubo_pool = create_descriptor_pool(device, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, max_frames_in_flight);
|
|
|
|
|
|
|
|
if(scene_ubo_pool == VK_NULL_HANDLE) {
|
|
|
|
|
|
|
|
fprintf(stderr, "failed to create vulkan scene descriptor pool\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
context->scene_ubo_pool = scene_ubo_pool;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutBinding scene_ubo_layout_binding = {
|
|
|
|
|
|
|
|
.binding = 0,
|
|
|
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
|
|
|
|
|
|
.descriptorCount = 1,
|
|
|
|
|
|
|
|
.pImmutableSamplers = 0,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayout scene_ubo_layout = create_descriptor_set_layout(device, &scene_ubo_layout_binding, 1);
|
|
|
|
|
|
|
|
if(scene_ubo_layout == VK_NULL_HANDLE) {
|
|
|
|
|
|
|
|
fprintf(stderr, "failed to create vulkan scene descriptor layout\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
context->scene_ubo_layout = scene_ubo_layout;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorSet* scene_ubo_descriptors = create_descriptor_sets(context->device, context->scene_ubo_layout, context->scene_ubo_pool, max_frames_in_flight);
|
|
|
|
|
|
|
|
if(scene_ubo_descriptors == 0) {
|
|
|
|
|
|
|
|
fprintf(stderr, "failed to create vulkan scene descriptore\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
context->scene_ubo_descriptors = scene_ubo_descriptors;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AllocatedBuffer* scene_ubos = allocate_buffers(context->physical_device, context->device, sizeof(struct SceneUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, max_frames_in_flight);
|
|
|
|
|
|
|
|
if(scene_ubos == 0) {
|
|
|
|
|
|
|
|
fprintf(stderr, "failed to create vulkan scnene ubo buffers\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
context->scene_ubos = scene_ubos;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void** scene_ubo_ptrs = malloc(sizeof(void*)*max_frames_in_flight);
|
|
|
|
|
|
|
|
if(scene_ubo_ptrs == 0) {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
context->scene_ubo_ptrs = scene_ubo_ptrs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < max_frames_in_flight; i++) {
|
|
|
|
|
|
|
|
VkResult result = vkMapMemory(device, context->scene_ubos[i].memory, 0, sizeof(struct SceneUBO), 0, &context->scene_ubo_ptrs[i]);
|
|
|
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
|
|
|
for(uint32_t j = 0; j < i; j++) {
|
|
|
|
|
|
|
|
vkUnmapMemory(device, context->scene_ubos[j].memory);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "failed to map vulkan buffers to pointers for scene ubos\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < max_frames_in_flight; i++) {
|
|
|
|
|
|
|
|
VkDescriptorBufferInfo buffer_info = {};
|
|
|
|
|
|
|
|
buffer_info.buffer = context->scene_ubos[i].buffer;
|
|
|
|
|
|
|
|
buffer_info.offset = 0;
|
|
|
|
|
|
|
|
buffer_info.range = sizeof(struct SceneUBO);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkWriteDescriptorSet descriptor_write = {};
|
|
|
|
|
|
|
|
descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
|
|
|
|
|
descriptor_write.dstSet = context->scene_ubo_descriptors[i];
|
|
|
|
|
|
|
|
descriptor_write.dstBinding = 0;
|
|
|
|
|
|
|
|
descriptor_write.dstArrayElement = 0;
|
|
|
|
|
|
|
|
descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
|
|
|
|
|
|
descriptor_write.descriptorCount = 1;
|
|
|
|
|
|
|
|
descriptor_write.pBufferInfo = &buffer_info;
|
|
|
|
|
|
|
|
descriptor_write.pImageInfo = 0;
|
|
|
|
|
|
|
|
descriptor_write.pTexelBufferView = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/basic.vert.spv", device);
|
|
|
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/basic.frag.spv", device);
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
|
|
|
|
|
|
|
shader_stages[0].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
|
|
|
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
|
|
|
|
shader_stages[0].module = vert_shader;
|
|
|
|
|
|
|
|
shader_stages[0].pName = "main";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shader_stages[1].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
|
|
|
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
|
|
|
|
shader_stages[1].module = frag_shader;
|
|
|
|
|
|
|
|
shader_stages[1].pName = "main";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Material simple_mesh_material = create_material(context->device, context->swapchain_extent, context->render_pass, 2, shader_stages, context->scene_ubo_layout, 0, 0, 0, 0);
|
|
|
|
if(simple_mesh_material.pipeline == VK_NULL_HANDLE) {
|
|
|
|
if(simple_mesh_material.pipeline == VK_NULL_HANDLE) {
|
|
|
|
fprintf(stderr, "failed to create simple mesh material\n");
|
|
|
|
fprintf(stderr, "failed to create simple mesh material\n");
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
@ -1626,23 +1654,18 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
return context;
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t counter = 0;
|
|
|
|
|
|
|
|
VkResult update_ubo(void** buffers, uint32_t frame_index) {
|
|
|
|
VkResult update_ubo(void** buffers, uint32_t frame_index) {
|
|
|
|
struct ShaderUBO ubo = {};
|
|
|
|
struct SceneUBO ubo = {};
|
|
|
|
glm_mat4_identity(ubo.proj);
|
|
|
|
glm_mat4_identity(ubo.proj);
|
|
|
|
glm_mat4_identity(ubo.view);
|
|
|
|
glm_mat4_identity(ubo.view);
|
|
|
|
|
|
|
|
|
|
|
|
vec3 axis = {0.0f, 0.0f, 1.0f};
|
|
|
|
|
|
|
|
glm_rotate_make(ubo.model, counter/100.0f, axis);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(buffers[frame_index], (void*)&ubo, sizeof(ubo));
|
|
|
|
memcpy(buffers[frame_index], (void*)&ubo, sizeof(ubo));
|
|
|
|
counter += 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult draw_frame(VulkanContext* context) {
|
|
|
|
VkResult draw_frame(VulkanContext* context) {
|
|
|
|
update_ubo(context->simple_mesh_material.uniform_buffer_ptrs, context->current_frame);
|
|
|
|
update_ubo(context->scene_ubo_ptrs, context->current_frame);
|
|
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
VkResult result;
|
|
|
|
result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
|
|
|
|
result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
|
|
|
@ -1666,7 +1689,9 @@ VkResult draw_frame(VulkanContext* context) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = record_command_buffer_mesh(context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent, context->simple_mesh_material, context->triangle_mesh, context->current_frame);
|
|
|
|
uint32_t mesh_counts[] = {1};
|
|
|
|
|
|
|
|
Mesh* meshes[] = {&context->triangle_mesh};
|
|
|
|
|
|
|
|
result = record_command_buffer_scene(1, &context->simple_mesh_material, (uint32_t*)&mesh_counts, (Mesh**)meshes, context->scene_ubo_descriptors[context->current_frame], context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|