|
|
|
@ -64,6 +64,24 @@ typedef struct TextureStruct {
|
|
|
|
|
VkSampler sampler;
|
|
|
|
|
} Texture;
|
|
|
|
|
|
|
|
|
|
// Defines how a mesh is read from a buffer into a graphics pipeline
|
|
|
|
|
typedef struct MeshTypeStruct {
|
|
|
|
|
uint32_t bindings_count;
|
|
|
|
|
VkVertexInputBindingDescription* bindings;
|
|
|
|
|
|
|
|
|
|
uint32_t attributes_count;
|
|
|
|
|
VkVertexInputAttributeDescription* attributes;
|
|
|
|
|
} MeshType;
|
|
|
|
|
|
|
|
|
|
// Defines what descriptors are bound at two different upate rates for the pipeline
|
|
|
|
|
typedef struct PipelineLayoutStruct {
|
|
|
|
|
uint32_t mesh_bindings_count;
|
|
|
|
|
VkDescriptorSetLayoutBinding* mesh_bindings;
|
|
|
|
|
|
|
|
|
|
uint32_t material_bindings_count;
|
|
|
|
|
VkDescriptorSetLayoutBinding* material_bindings;
|
|
|
|
|
} PipelineLayout;
|
|
|
|
|
|
|
|
|
|
typedef struct MeshStruct {
|
|
|
|
|
uint32_t vertex_count;
|
|
|
|
|
AllocatedBuffer vertex_buffer;
|
|
|
|
@ -93,7 +111,7 @@ typedef struct MaterialStruct {
|
|
|
|
|
VkDescriptorSetLayout material_set_layout;
|
|
|
|
|
VkDescriptorSetLayout mesh_set_layout;
|
|
|
|
|
|
|
|
|
|
VkPipelineLayout pipeline_layout;
|
|
|
|
|
VkPipelineLayout layout;
|
|
|
|
|
VkPipeline pipeline;
|
|
|
|
|
} Material;
|
|
|
|
|
|
|
|
|
@ -1469,10 +1487,7 @@ VkPipeline create_graphics_pipeline(
|
|
|
|
|
VkRenderPass render_pass,
|
|
|
|
|
uint32_t shader_stage_count,
|
|
|
|
|
VkPipelineShaderStageCreateInfo* shader_stages,
|
|
|
|
|
uint32_t bindings_count,
|
|
|
|
|
VkVertexInputBindingDescription* bindings,
|
|
|
|
|
uint32_t attributes_count,
|
|
|
|
|
VkVertexInputAttributeDescription* attributes
|
|
|
|
|
MeshType mesh_type
|
|
|
|
|
) {
|
|
|
|
|
VkDynamicState dynamic_states[] = {
|
|
|
|
|
VK_DYNAMIC_STATE_VIEWPORT,
|
|
|
|
@ -1487,15 +1502,15 @@ VkPipeline create_graphics_pipeline(
|
|
|
|
|
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
|
|
|
|
|
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
|
|
|
vertex_input_info.vertexBindingDescriptionCount = bindings_count;
|
|
|
|
|
vertex_input_info.pVertexBindingDescriptions = bindings;
|
|
|
|
|
vertex_input_info.vertexAttributeDescriptionCount = attributes_count;
|
|
|
|
|
vertex_input_info.pVertexAttributeDescriptions = attributes;
|
|
|
|
|
vertex_input_info.vertexBindingDescriptionCount = mesh_type.bindings_count;
|
|
|
|
|
vertex_input_info.pVertexBindingDescriptions = mesh_type.bindings;
|
|
|
|
|
vertex_input_info.vertexAttributeDescriptionCount = mesh_type.attributes_count;
|
|
|
|
|
vertex_input_info.pVertexAttributeDescriptions = mesh_type.attributes;
|
|
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assemvly_info = {};
|
|
|
|
|
input_assemvly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
|
|
|
input_assemvly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
|
|
|
input_assemvly_info.primitiveRestartEnable = VK_FALSE;
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {};
|
|
|
|
|
input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
|
|
|
input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
|
|
|
input_assembly_info.primitiveRestartEnable = VK_FALSE;
|
|
|
|
|
|
|
|
|
|
VkViewport viewport = {};
|
|
|
|
|
viewport.x = 0.0f;
|
|
|
|
@ -1578,7 +1593,7 @@ VkPipeline create_graphics_pipeline(
|
|
|
|
|
pipeline_info.stageCount = shader_stage_count;
|
|
|
|
|
pipeline_info.pStages = shader_stages;
|
|
|
|
|
pipeline_info.pVertexInputState = &vertex_input_info;
|
|
|
|
|
pipeline_info.pInputAssemblyState = &input_assemvly_info;
|
|
|
|
|
pipeline_info.pInputAssemblyState = &input_assembly_info;
|
|
|
|
|
pipeline_info.pViewportState = &viewport_state;
|
|
|
|
|
pipeline_info.pRasterizationState = &raster_info;
|
|
|
|
|
pipeline_info.pDepthStencilState = 0;
|
|
|
|
@ -1687,7 +1702,7 @@ void record_command_buffer_mesh(Mesh mesh, VkCommandBuffer command_buffer) {
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.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);
|
|
|
|
|
}
|
|
|
|
@ -1877,16 +1892,8 @@ Material create_material(
|
|
|
|
|
uint32_t shader_stage_count,
|
|
|
|
|
VkPipelineShaderStageCreateInfo* shader_stages,
|
|
|
|
|
VkDescriptorSetLayout scene_ubo_layout,
|
|
|
|
|
uint32_t material_set_bindings_count,
|
|
|
|
|
VkDescriptorSetLayoutBinding* material_set_bindings,
|
|
|
|
|
uint32_t mesh_set_bindings_count,
|
|
|
|
|
VkDescriptorSetLayoutBinding* mesh_set_bindings,
|
|
|
|
|
uint32_t pcr_count,
|
|
|
|
|
VkPushConstantRange* pcrs,
|
|
|
|
|
uint32_t vertex_bindings_count,
|
|
|
|
|
VkVertexInputBindingDescription* vertex_bindings,
|
|
|
|
|
uint32_t attributes_count,
|
|
|
|
|
VkVertexInputAttributeDescription* attributes
|
|
|
|
|
PipelineLayout pipeline_layout,
|
|
|
|
|
MeshType mesh_type
|
|
|
|
|
) {
|
|
|
|
|
Material zero_material = {
|
|
|
|
|
.pipeline = VK_NULL_HANDLE,
|
|
|
|
@ -1897,11 +1904,11 @@ Material create_material(
|
|
|
|
|
VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, VK_NULL_HANDLE, VK_NULL_HANDLE};
|
|
|
|
|
uint32_t num_layouts = 1;
|
|
|
|
|
|
|
|
|
|
if(material_set_bindings_count > 0) {
|
|
|
|
|
if(pipeline_layout.material_bindings_count > 0) {
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
|
|
|
.bindingCount = material_set_bindings_count,
|
|
|
|
|
.pBindings = material_set_bindings,
|
|
|
|
|
.bindingCount = pipeline_layout.material_bindings_count,
|
|
|
|
|
.pBindings = pipeline_layout.material_bindings,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &material_set_layout);
|
|
|
|
@ -1913,11 +1920,11 @@ Material create_material(
|
|
|
|
|
num_layouts += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(mesh_set_bindings_count > 0) {
|
|
|
|
|
if(pipeline_layout.mesh_bindings_count > 0) {
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo layout_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
|
|
|
.bindingCount = mesh_set_bindings_count,
|
|
|
|
|
.pBindings = mesh_set_bindings,
|
|
|
|
|
.bindingCount = pipeline_layout.mesh_bindings_count,
|
|
|
|
|
.pBindings = pipeline_layout.mesh_bindings,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &mesh_set_layout);
|
|
|
|
@ -1929,28 +1936,19 @@ Material create_material(
|
|
|
|
|
num_layouts += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPushConstantRange* all_pcrs = malloc(sizeof(VkPushConstantRange)*(0+pcr_count));
|
|
|
|
|
if((all_pcrs == 0) && (pcr_count != 0)) {
|
|
|
|
|
return zero_material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < pcr_count; i++) {
|
|
|
|
|
all_pcrs[i] = pcrs[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPipelineLayout pipeline_layout = create_pipeline_layout(device, num_layouts, all_layouts, pcr_count, all_pcrs);
|
|
|
|
|
if(pipeline_layout == VK_NULL_HANDLE) {
|
|
|
|
|
free(all_pcrs);
|
|
|
|
|
VkPipelineLayout layout = create_pipeline_layout(device, num_layouts, all_layouts, 0, 0);
|
|
|
|
|
if(layout == VK_NULL_HANDLE) {
|
|
|
|
|
return zero_material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPipeline pipeline = create_graphics_pipeline(device, extent, pipeline_layout, render_pass, shader_stage_count, shader_stages, vertex_bindings_count, vertex_bindings, attributes_count, attributes);
|
|
|
|
|
VkPipeline pipeline = create_graphics_pipeline(device, extent, layout, render_pass, shader_stage_count, shader_stages, mesh_type);
|
|
|
|
|
if(pipeline == VK_NULL_HANDLE) {
|
|
|
|
|
return zero_material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material material = {
|
|
|
|
|
.pipeline_layout = pipeline_layout,
|
|
|
|
|
.layout = layout,
|
|
|
|
|
.pipeline = pipeline,
|
|
|
|
|
|
|
|
|
|
.material_set_layout = material_set_layout,
|
|
|
|
@ -1976,18 +1974,18 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[1] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.stride = sizeof(struct Vertex),
|
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
|
|
|
.binding = 0, // Which buffer 'binding' to use
|
|
|
|
|
.stride = sizeof(struct Vertex), // How many bytes to increase the index between instance
|
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX, // Whether an instance is a vertex or an index
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputAttributeDescription attributes[2] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 0,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct Vertex, pos),
|
|
|
|
|
.binding = 0, // Which buffer 'binding' to use
|
|
|
|
|
.location = 0, // Which 'location' to export as to shader
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT, // What format to interpret as for shader
|
|
|
|
|
.offset = offsetof(struct Vertex, pos), // What offset from instance start
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
@ -1997,7 +1995,18 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, 0, 0, 0, 0, 0, 0, 1, bindings, 2, attributes);
|
|
|
|
|
MeshType simple_mesh_type = {
|
|
|
|
|
.bindings = bindings,
|
|
|
|
|
.bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
|
|
|
|
|
.attributes = attributes,
|
|
|
|
|
.attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PipelineLayout simple_layout = {
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, simple_layout, simple_mesh_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout) {
|
|
|
|
@ -2061,7 +2070,19 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, 0, 0, 1, mesh_set_bindings, 0, 0, 1, bindings, 3, attributes);
|
|
|
|
|
MeshType textured_mesh_type = {
|
|
|
|
|
.bindings = bindings,
|
|
|
|
|
.bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
|
|
|
|
|
.attributes = attributes,
|
|
|
|
|
.attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PipelineLayout texture_layout = {
|
|
|
|
|
.mesh_bindings_count = sizeof(mesh_set_bindings)/sizeof(VkDescriptorSetLayoutBinding),
|
|
|
|
|
.mesh_bindings = mesh_set_bindings,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, texture_layout, textured_mesh_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|