@ -64,156 +64,6 @@ typedef struct TextureStruct {
VkSampler sampler ;
} Texture ;
typedef struct EntryStruct {
uint32_t key ;
void * value ;
} Entry ;
typedef struct MapStruct {
uint32_t buckets_count ;
Entry * * buckets ;
uint32_t * bucket_sizes ;
uint32_t * bucket_usage ;
} Map ;
Map map_create ( uint32_t buckets_count , uint32_t initial_bucket_size ) {
Map zero = { } ;
Entry * * buckets = malloc ( sizeof ( Entry * ) * buckets_count ) ;
if ( buckets = = 0 ) {
return zero ;
}
uint32_t * bucket_sizes = malloc ( sizeof ( uint32_t ) * buckets_count ) ;
if ( bucket_sizes = = 0 ) {
free ( buckets ) ;
return zero ;
}
uint32_t * bucket_usage = malloc ( sizeof ( uint32_t ) * buckets_count ) ;
if ( bucket_usage = = 0 ) {
free ( bucket_usage ) ;
free ( buckets ) ;
return zero ;
}
for ( uint32_t i = 0 ; i < buckets_count ; i + + ) {
Entry * bucket = malloc ( sizeof ( Entry ) * initial_bucket_size ) ;
if ( bucket = = 0 ) {
for ( uint32_t j = 0 ; j < i ; j + + ) {
free ( buckets [ j ] ) ;
}
free ( bucket_sizes ) ;
free ( buckets ) ;
return zero ;
}
buckets [ i ] = bucket ;
bucket_sizes [ i ] = initial_bucket_size ;
bucket_usage [ i ] = 0 ;
}
Map ret = {
. buckets_count = buckets_count ,
. bucket_sizes = bucket_sizes ,
. bucket_usage = bucket_usage ,
. buckets = buckets ,
} ;
return ret ;
}
typedef struct MaybeValueStruct {
bool has_value ;
void * value ;
} MaybeValue ;
MaybeValue map_lookup ( Map map , uint32_t key ) {
MaybeValue ret = {
. has_value = false ,
. value = 0 ,
} ;
uint32_t bucket_index = key % map . buckets_count ;
for ( uint32_t i = 0 ; i < map . bucket_usage [ bucket_index ] ; i + + ) {
if ( map . buckets [ bucket_index ] [ i ] . key = = key ) {
ret . has_value = true ;
ret . value = map . buckets [ bucket_index ] [ i ] . value ;
}
}
return ret ;
}
bool map_add ( Map * map , uint32_t key , void * value ) {
uint32_t bucket_index = key % map - > buckets_count ;
for ( uint32_t i = 0 ; i < map - > bucket_usage [ bucket_index ] ; i + + ) {
if ( map - > buckets [ bucket_index ] [ i ] . key = = key ) {
map - > buckets [ bucket_index ] [ i ] . value = value ;
return true ;
}
}
if ( map - > bucket_usage [ bucket_index ] < map - > bucket_sizes [ bucket_index ] ) {
map - > buckets [ bucket_index ] [ map - > bucket_usage [ bucket_index ] ] . key = key ;
map - > buckets [ bucket_index ] [ map - > bucket_usage [ bucket_index ] ] . value = value ;
map - > bucket_usage [ bucket_index ] + = 1 ;
return true ;
}
Entry * new_bucket = realloc ( map - > buckets [ bucket_index ] , 2 * map - > bucket_sizes [ bucket_index ] ) ;
if ( new_bucket = = 0 ) {
return false ;
}
map - > bucket_usage [ bucket_index ] + = 1 ;
map - > bucket_sizes [ bucket_index ] * = 2 ;
map - > buckets [ bucket_index ] = new_bucket ;
map - > buckets [ bucket_index ] [ map - > bucket_usage [ bucket_index ] ] . key = key ;
map - > buckets [ bucket_index ] [ map - > bucket_usage [ bucket_index ] ] . value = value ;
return true ;
}
MaybeValue map_del ( Map * map , uint32_t key ) {
MaybeValue ret = {
. has_value = false ,
. value = 0 ,
} ;
uint32_t bucket_index = key % map - > buckets_count ;
for ( uint32_t i = 0 ; i < map - > bucket_usage [ bucket_index ] ; i + + ) {
if ( map - > buckets [ bucket_index ] [ i ] . key = = key ) {
ret . value = map - > buckets [ bucket_index ] [ i ] . value ;
ret . has_value = true ;
if ( map - > bucket_usage [ bucket_index ] > 1 ) {
map - > buckets [ bucket_index ] [ i ] = map - > buckets [ bucket_index ] [ map - > bucket_usage [ bucket_index ] - 1 ] ;
}
map - > bucket_usage [ bucket_index ] - = 1 ;
break ;
}
}
return ret ;
}
void map_destroy ( Map map ) {
for ( uint32_t i = 0 ; i < map . buckets_count ; i + + ) {
free ( map . buckets [ i ] ) ;
}
free ( map . buckets ) ;
free ( map . bucket_sizes ) ;
free ( map . bucket_usage ) ;
}
# define ATTRIBUTE_ID_MESH 0x00000001
# define ATTRIBUTE_ID_MATERIAL 0x00000002
typedef struct ObjectStruct {
Map attributes ;
} Object ;
// Defines how a mesh is read from a buffer into a graphics pipeline
typedef struct MeshTypeStruct {
uint32_t bindings_count ;
@ -240,16 +90,29 @@ typedef struct MeshStruct {
AllocatedBuffer index_buffer ;
} Mesh ;
typedef struct DescriptorPoolStruct {
VkDescriptorPool handle ;
uint32_t allocated ;
} DescriptorPool ;
typedef struct GrowingDescriptorPoolStruct {
uint32_t num_pool_sizes ;
VkDescriptorPoolSize * pool_sizes ;
uint32_t sets_per_pool ;
VkDescriptorPoolCreateInfo pool_info ;
VkDescriptorSetLayout set_layout ;
uint32_t num_pools ;
DescriptorPool * pools ;
} GrowingDescriptorPool ;
typedef struct MaterialStruct {
VkDescriptorSetLayout material_set_layout ;
VkDescriptorSetLayout mesh_set_layout ;
VkPipelineLayout layout ;
VkPipeline pipeline ;
VkDescriptorPool material_descriptor_pool ;
VkDescriptorSet * material_descriptors ;
uint32_t material_descriptors_count ;
} Material ;
typedef struct VulkanContextStruct {
@ -292,9 +155,9 @@ typedef struct VulkanContextStruct {
VkCommandPool graphics_command_pool ;
VkCommandPool transfer_command_pool ;
VkDescriptorPool scene_ pool;
VkDescriptorSetLayout scene_ descriptor _layout;
VkDescriptorSet * scene_ descriptors;
VkDescriptorPool scene_ ubo_ pool;
VkDescriptorSetLayout scene_ ubo _layout;
VkDescriptorSet * scene_ ubo_ descriptors;
AllocatedBuffer * scene_ubos ;
void * * scene_ubo_ptrs ;
@ -302,8 +165,6 @@ typedef struct VulkanContextStruct {
Mesh triangle_mesh_textured ;
Material simple_mesh_material ;
Material texture_mesh_material ;
Object triangle_object ;
Object triangle_object_textured ;
uint32_t current_frame ;
} VulkanContext ;
@ -439,6 +300,122 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(
return VK_FALSE ;
}
GrowingDescriptorPool create_growing_descriptor_pool ( VkDevice device , uint32_t num_bindings , VkDescriptorSetLayoutBinding * bindings , uint32_t sets_per_pool ) {
GrowingDescriptorPool ret = {
. sets_per_pool = sets_per_pool ,
} ;
VkDescriptorSetLayoutCreateInfo layout_info = {
. sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO ,
. bindingCount = num_bindings ,
. pBindings = bindings ,
} ;
VkDescriptorSetLayout layout ;
VkResult result = vkCreateDescriptorSetLayout ( device , & layout_info , 0 , & layout ) ;
if ( result ! = VK_SUCCESS ) {
return ret ;
}
VkDescriptorPoolSize * pool_sizes = malloc ( sizeof ( VkDescriptorPoolSize ) * num_bindings ) ;
if ( pool_sizes = = 0 ) {
return ret ;
}
for ( uint32_t i = 0 ; i < num_bindings ; i + + ) {
VkDescriptorPoolSize size = {
. type = bindings [ i ] . descriptorType ,
. descriptorCount = bindings [ i ] . descriptorCount * sets_per_pool ,
} ;
pool_sizes [ i ] = size ;
}
VkDescriptorPoolCreateInfo pool_info = {
. sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO ,
. poolSizeCount = num_bindings ,
. pPoolSizes = pool_sizes ,
. maxSets = sets_per_pool ,
} ;
DescriptorPool * pools = malloc ( sizeof ( DescriptorPool ) ) ;
if ( pools = = 0 ) {
free ( pool_sizes ) ;
return ret ;
}
result = vkCreateDescriptorPool ( device , & pool_info , 0 , & pools [ 0 ] . handle ) ;
if ( result ! = VK_SUCCESS ) {
free ( pool_sizes ) ;
free ( pools ) ;
}
ret . set_layout = layout ;
ret . pool_info = pool_info ;
ret . pools = pools ;
ret . num_pools = 1 ;
ret . pool_info = pool_info ;
ret . pool_sizes = pool_sizes ;
return ret ;
}
DescriptorPool * grow_descriptor_pool ( VkDevice device , GrowingDescriptorPool * pool ) {
VkDescriptorPool handle ;
VkResult result = vkCreateDescriptorPool ( device , & pool - > pool_info , 0 , & handle ) ;
if ( result ! = VK_SUCCESS ) {
return 0 ;
}
uint32_t new_size = pool - > num_pools + 1 ;
DescriptorPool * new_pools = realloc ( pool - > pools , sizeof ( DescriptorPool ) * new_size ) ;
if ( new_pools = = 0 ) {
return 0 ;
}
new_pools [ new_size - 1 ] . allocated = 0 ;
new_pools [ new_size - 1 ] . handle = handle ;
pool - > pools = new_pools ;
pool - > num_pools = new_size ;
return & new_pools [ new_size - 1 ] ;
}
VkDescriptorSet allocate_descriptor_set ( VkDevice device , GrowingDescriptorPool * pool ) {
DescriptorPool * selected_pool = 0 ;
uint32_t index = 0 ;
for ( uint32_t i = 0 ; i < pool - > num_pools ; i + + ) {
if ( pool - > pools [ i ] . allocated < pool - > sets_per_pool ) {
selected_pool = & pool - > pools [ i ] ;
index = i ;
break ;
}
}
if ( selected_pool = = 0 ) {
selected_pool = grow_descriptor_pool ( device , pool ) ;
index = pool - > num_pools - 1 ;
if ( selected_pool = = 0 ) {
return VK_NULL_HANDLE ;
}
}
VkDescriptorSetAllocateInfo alloc_info = {
. sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO ,
. descriptorPool = selected_pool - > handle ,
. pSetLayouts = & pool - > set_layout ,
. descriptorSetCount = 1 ,
} ;
VkDescriptorSet new_set ;
VkResult result = vkAllocateDescriptorSets ( device , & alloc_info , & new_set ) ;
if ( result ! = VK_SUCCESS ) {
return VK_NULL_HANDLE ;
}
pool - > pools [ index ] . allocated + = 1 ;
return new_set ;
}
VkDescriptorSet * create_descriptor_sets ( VkDevice device , VkDescriptorSetLayout layout , VkDescriptorPool pool , uint32_t count ) {
VkDescriptorSetLayout * layouts = malloc ( sizeof ( VkDescriptorSetLayout ) * count ) ;
if ( layouts = = 0 ) {
@ -1079,6 +1056,24 @@ VkRenderPass create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFo
return render_pass ;
}
VkPipelineLayout create_pipeline_layout ( VkDevice device , uint32_t set_count , VkDescriptorSetLayout * sets , uint32_t pcr_count , VkPushConstantRange * pcrs ) {
VkPipelineLayout layout ;
VkPipelineLayoutCreateInfo layout_info = { } ;
layout_info . sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO ;
layout_info . setLayoutCount = set_count ;
layout_info . pSetLayouts = sets ;
layout_info . pushConstantRangeCount = pcr_count ;
layout_info . pPushConstantRanges = pcrs ;
VkResult result ;
result = vkCreatePipelineLayout ( device , & layout_info , 0 , & layout ) ;
if ( result ! = VK_SUCCESS ) {
return VK_NULL_HANDLE ;
}
return layout ;
}
uint32_t find_memory_type ( VkPhysicalDevice physical_device , uint32_t type_filter , VkMemoryPropertyFlags properties ) {
VkPhysicalDeviceMemoryProperties memory_properties ;
vkGetPhysicalDeviceMemoryProperties ( physical_device , & memory_properties ) ;
@ -1695,35 +1690,25 @@ VkResult recreate_swap_chain(VulkanContext* context, VkExtent2D new_extent) {
return VK_SUCCESS ;
}
void command_draw_mesh ( Object object , VkCommandBuffer command_buffer ) {
MaybeValue maybe_mesh = map_lookup ( object . attributes , ATTRIBUTE_ID_MESH ) ;
if ( maybe_mesh . has_value = = false ) {
return ;
}
Mesh * mesh = maybe_mesh . value ;
VkBuffer vertex_buffers [ ] = { mesh - > vertex_buffer . buffer } ;
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 ) ;
vkCmdBindIndexBuffer ( command_buffer , mesh . index_buffer . buffer , 0 , VK_INDEX_TYPE_UINT16 ) ;
vkCmdDrawIndexed ( command_buffer , mesh - > index_count , 1 , 0 , 0 , 0 ) ;
vkCmdDrawIndexed ( command_buffer , mesh . index_count , 1 , 0 , 0 , 0 ) ;
}
void command_draw _material( Material material , uint32_t mesh_count , Object* objects , uint32_t frame_num , VkDescriptorSet * scene_descriptors , 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 . layout , 0 , 1 , & scene_descriptors [ frame_num ] , 0 , 0 ) ;
if ( material . material_descriptors ! = 0 ) {
vkCmdBindDescriptorSets ( command_buffer , VK_PIPELINE_BIND_POINT_GRAPHICS , material . layout , 1 , 1 , & material . material_descriptors [ frame_num ] , 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 + + ) {
command_draw_mesh( object s[ i ] , command_buffer ) ;
record_command_buffer_mesh ( meshes [ i ] , command_buffer ) ;
}
}
VkResult command_draw _scene( uint32_t materials_count , Material * materials , uint32_t * mesh_counts , Object* * objects , uint32_t frame_num , VkDescriptorSet * scene_descriptors , VkCommandBuffer command_buffer , VkRenderPass render_pass , VkFramebuffer framebuffer , VkExtent2D extent ) {
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 = { } ;
begin_info . sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO ;
begin_info . flags = 0 ;
@ -1772,7 +1757,7 @@ VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint3
vkCmdSetScissor ( command_buffer , 0 , 1 , & scissor ) ;
for ( uint i = 0 ; i < materials_count ; i + + ) {
command_draw _material( materials [ i ] , mesh_counts [ i ] , objects[ i ] , frame_num , scene_descriptors , command_buffer ) ;
record_command_buffer _material( materials [ i ] , mesh_counts [ i ] , meshes[ i ] , scene_ubo_descriptor , command_buffer ) ;
}
vkCmdEndRenderPass ( command_buffer ) ;
@ -1869,58 +1854,6 @@ Mesh load_texture_mesh(VkPhysicalDevice physical_device, VkDevice device, struct
return mesh ;
}
Object create_object ( ) {
Object ret = {
. attributes = {
. buckets = 0 ,
} ,
} ;
Map attributes = map_create ( 8 , 2 ) ;
if ( attributes . buckets = = 0 ) {
return ret ;
}
ret . attributes = attributes ;
return ret ;
}
Object create_renderable ( Mesh * mesh , Material * material ) {
Object zero = {
. attributes = {
. buckets = 0 ,
} ,
} ;
if ( mesh = = 0 | | material = = 0 ) {
return zero ;
}
Map attributes = map_create ( 8 , 2 ) ;
if ( attributes . buckets = = 0 ) {
return zero ;
}
bool result = map_add ( & attributes , ATTRIBUTE_ID_MESH , mesh ) ;
if ( result = = false ) {
map_destroy ( attributes ) ;
return zero ;
}
result = map_add ( & attributes , ATTRIBUTE_ID_MATERIAL , material ) ;
if ( result = = false ) {
map_destroy ( attributes ) ;
return zero ;
}
Object ret = {
. attributes = attributes ,
} ;
return ret ;
}
Mesh load_simple_mesh ( VkPhysicalDevice physical_device , VkDevice device , struct Vertex * vertices , uint32_t vertex_count , uint16_t * indices , uint32_t index_count , VkCommandPool transfer_pool , VkQueue transfer_queue ) {
Mesh mesh = { } ;
mesh . vertex_buffer . buffer = VK_NULL_HANDLE ;
@ -1950,6 +1883,8 @@ Mesh load_simple_mesh(VkPhysicalDevice physical_device, VkDevice device, struct
return mesh ;
}
uint32_t HARDCODED_SETS_PER_POOL = 10 ;
Material create_material (
VkDevice device ,
VkExtent2D extent ,
@ -1958,8 +1893,7 @@ Material create_material(
VkPipelineShaderStageCreateInfo * shader_stages ,
VkDescriptorSetLayout scene_ubo_layout ,
PipelineLayout pipeline_layout ,
MeshType mesh_type ,
uint32_t max_frames_in_flight
MeshType mesh_type
) {
Material zero_material = {
. pipeline = VK_NULL_HANDLE ,
@ -1970,9 +1904,6 @@ Material create_material(
VkDescriptorSetLayout all_layouts [ 3 ] = { scene_ubo_layout , VK_NULL_HANDLE , VK_NULL_HANDLE } ;
uint32_t num_layouts = 1 ;
VkDescriptorPool material_descriptor_pool = VK_NULL_HANDLE ;
VkDescriptorSet * material_descriptors = 0 ;
if ( pipeline_layout . material_bindings_count > 0 ) {
VkDescriptorSetLayoutCreateInfo layout_info = {
. sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO ,
@ -1985,61 +1916,6 @@ Material create_material(
return zero_material ;
}
material_descriptors = malloc ( sizeof ( VkDescriptorSet ) * max_frames_in_flight ) ;
if ( material_descriptors = = 0 ) {
return zero_material ;
}
VkDescriptorPoolSize * pool_sizes = malloc ( sizeof ( VkDescriptorPool ) * pipeline_layout . material_bindings_count ) ;
if ( pool_sizes = = 0 ) {
return zero_material ;
}
for ( uint32_t i = 0 ; i < pipeline_layout . material_bindings_count ; i + + ) {
VkDescriptorPoolSize pool_size = {
. type = pipeline_layout . material_bindings [ i ] . descriptorType ,
. descriptorCount = pipeline_layout . material_bindings [ i ] . descriptorCount ,
} ;
pool_sizes [ i ] = pool_size ;
}
VkDescriptorPoolCreateInfo pool_info = {
. sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO ,
. poolSizeCount = pipeline_layout . material_bindings_count ,
. maxSets = max_frames_in_flight ,
. pPoolSizes = pool_sizes ,
} ;
result = vkCreateDescriptorPool ( device , & pool_info , 0 , & material_descriptor_pool ) ;
free ( pool_sizes ) ;
if ( result ! = VK_SUCCESS ) {
return zero_material ;
}
VkDescriptorSetLayout * set_layouts = malloc ( sizeof ( VkDescriptorSetLayout ) * max_frames_in_flight ) ;
if ( set_layouts = = 0 ) {
vkDestroyDescriptorPool ( device , material_descriptor_pool , 0 ) ;
return zero_material ;
}
for ( uint32_t i = 0 ; i < max_frames_in_flight ; i + + ) {
set_layouts [ i ] = material_set_layout ;
}
VkDescriptorSetAllocateInfo alloc_info = {
. sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO ,
. descriptorSetCount = max_frames_in_flight ,
. descriptorPool = material_descriptor_pool ,
. pSetLayouts = set_layouts ,
} ;
result = vkAllocateDescriptorSets ( device , & alloc_info , material_descriptors ) ;
free ( set_layouts ) ;
if ( result ! = VK_SUCCESS ) {
vkDestroyDescriptorPool ( device , material_descriptor_pool , 0 ) ;
return zero_material ;
}
all_layouts [ num_layouts ] = material_set_layout ;
num_layouts + = 1 ;
}
@ -2060,17 +1936,9 @@ Material create_material(
num_layouts + = 1 ;
}
VkPipelineLayout layout ;
VkPipelineLayoutCreateInfo layout_info = { } ;
layout_info . sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO ;
layout_info . setLayoutCount = num_layouts ;
layout_info . pSetLayouts = all_layouts ;
layout_info . pushConstantRangeCount = 0 ; // TODO
layout_info . pPushConstantRanges = 0 ; // TODO
Vk Result result = vkCreatePipelineLayout ( device , & layout_info , 0 , & layout ) ;
if ( result ! = VK_SUCCESS ) {
VkPipelineLayout layout = create_pipeline_layout ( device , num_layouts , all_layouts , 0 , 0 ) ;
if ( layout = = VK_NULL_HANDLE ) {
return zero_material ;
}
@ -2085,16 +1953,12 @@ Material create_material(
. material_set_layout = material_set_layout ,
. mesh_set_layout = mesh_set_layout ,
. material_descriptors = material_descriptors ,
. material_descriptor_pool = material_descriptor_pool ,
. material_descriptors_count = max_frames_in_flight ,
} ;
return material ;
}
Material create_simple_mesh_material ( VkDevice device , VkExtent2D extent , VkRenderPass render_pass , VkDescriptorSetLayout scene_ubo_layout , uint32_t max_frames_in_flight ) {
Material create_simple_mesh_material ( VkDevice device , VkExtent2D extent , VkRenderPass render_pass , VkDescriptorSetLayout scene_ubo_layout ) {
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 ] = { } ;
@ -2142,10 +2006,10 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
} ;
return create_material ( device , extent , render_pass , 2 , shader_stages , scene_ubo_layout , simple_layout , simple_mesh_type , max_frames_in_flight );
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 , uint32_t max_frames_in_flight ) {
Material create_texture_mesh_material ( VkDevice device , VkExtent2D extent , VkRenderPass render_pass , VkDescriptorSetLayout scene_ubo_layout ) {
VkShaderModule vert_shader = load_shader_file ( 2048 , " shader_src/texture.vert.spv " , device ) ;
if ( vert_shader = = VK_NULL_HANDLE ) {
Material tmp = { } ;
@ -2218,7 +2082,7 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend
. mesh_bindings = mesh_set_bindings ,
} ;
return create_material ( device , extent , render_pass , 2 , shader_stages , scene_ubo_layout , texture_layout , textured_mesh_type , max_frames_in_flight );
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 ) {
@ -2433,18 +2297,18 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
context - > in_flight_fences = if_fences ;
}
VkDescriptorPoolSize scene _pool_sizes[ ] = {
VkDescriptorPoolSize ubo _pool_sizes[ ] = {
{
. type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ,
. descriptorCount = max_frames_in_flight ,
}
} ;
VkDescriptorPool scene_ pool = create_descriptor_pool ( device , scene _pool_sizes, 1 , max_frames_in_flight ) ;
if ( scene_ pool = = VK_NULL_HANDLE ) {
VkDescriptorPool scene_ ubo_ pool = create_descriptor_pool ( device , ubo _pool_sizes, 1 , 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_ pool = scene _pool;
context - > scene_ ubo_ pool = scene _ubo _pool;
}
VkDescriptorSetLayoutBinding scene_ubo_layout_binding = {
@ -2455,20 +2319,20 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
. pImmutableSamplers = 0 ,
} ;
VkDescriptorSetLayout scene_ descriptor _layout = create_descriptor_set_layout ( device , & scene_ubo_layout_binding , 1 ) ;
if ( scene_ descriptor _layout = = VK_NULL_HANDLE ) {
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_ descriptor_layout = scene_descriptor _layout;
context - > scene_ ubo_layout = scene_ubo _layout;
}
VkDescriptorSet * scene_ descriptors = create_descriptor_sets ( context - > device , context - > scene_ descriptor _layout, context - > scene _pool, max_frames_in_flight ) ;
if ( scene_ descriptors = = 0 ) {
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_ descriptors = scene _descriptors;
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 ) ;
@ -2506,7 +2370,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
VkWriteDescriptorSet descriptor_write = { } ;
descriptor_write . sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET ;
descriptor_write . dstSet = context - > scene_ descriptors[ i ] ;
descriptor_write . dstSet = context - > scene_ ubo_ descriptors[ i ] ;
descriptor_write . dstBinding = 0 ;
descriptor_write . dstArrayElement = 0 ;
descriptor_write . descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ;
@ -2518,7 +2382,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
vkUpdateDescriptorSets ( device , 1 , & descriptor_write , 0 , 0 ) ;
}
Material simple_mesh_material = create_simple_mesh_material ( context - > device , context - > swapchain_extent , context - > render_pass , context - > scene_ descriptor_layout, max_frames_in_fligh t) ;
Material simple_mesh_material = create_simple_mesh_material ( context - > device , context - > swapchain_extent , context - > render_pass , context - > scene_ ubo_layou t) ;
if ( simple_mesh_material . pipeline = = VK_NULL_HANDLE ) {
fprintf ( stderr , " failed to create simple mesh material \n " ) ;
return 0 ;
@ -2526,28 +2390,20 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
context - > simple_mesh_material = simple_mesh_material ;
}
Mesh triangle_mesh = load_simple_mesh ( context - > physical_device , context - > device , ( struct Vertex * ) vertices , 4 , ( uint16_t * ) indices , 6 , context - > transfer_command_pool , context - > queues . transfer ) ;
if ( triangle_mesh . vertex_buffer . buffer = = VK_NULL_HANDLE ) {
fprintf ( stderr , " failed to load triangle mesh \n " ) ;
return 0 ;
} else {
context - > triangle_mesh = triangle_mesh ;
}
Object triangle_object = create_renderable ( & context - > triangle_mesh , & context - > simple_mesh_material ) ;
if ( triangle_object . attributes . buckets = = 0 ) {
fprintf ( stderr , " failed to create renderable triangle object \n " ) ;
Material texture_mesh_material = create_texture_mesh_material ( context - > device , context - > swapchain_extent , context - > render_pass , context - > scene_ubo_layout ) ;
if ( texture_mesh_material . pipeline = = VK_NULL_HANDLE ) {
fprintf ( stderr , " failed to create texture mesh material \n " ) ;
return 0 ;
} else {
context - > t riangle_object = triangle_object ;
context - > texture_mesh_material = texture_mesh_material ;
}
M aterial texture_mesh_material = create_texture_mesh_material ( context - > device, context - > swapchain_extent, context - > render_pass , context - > scene_descriptor_layout , max_frames_in_flight ) ;
if ( t exture_mesh_material. pipeline = = VK_NULL_HANDLE ) {
fprintf ( stderr , " failed to create texture mesh material \n " ) ;
Mesh triangle_mesh = load_simple_mesh ( context - > physical_device , context - > device , ( struct Vertex * ) vertices , 4 , ( uint16_t * ) indices , 6 , context - > transfer_command_pool , context - > queues . transfer ) ;
if ( triangle_mesh . vertex_buffer . buffer = = VK_NULL_HANDLE ) {
fprintf ( stderr , " failed to load triangle mesh \n " ) ;
return 0 ;
} else {
context - > t extu re_mesh_material = t extu re_mesh_material ;
context - > t riangl e_mesh = t riangl e_mesh;
}
Mesh triangle_mesh_textured = load_texture_mesh ( context - > physical_device , context - > device , ( struct TextureVertex * ) texture_vertices , 4 , ( uint16_t * ) indices , 6 , context - > transfer_command_pool , context - > queues . transfer ) ;
@ -2558,14 +2414,6 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
context - > triangle_mesh_textured = triangle_mesh_textured ;
}
Object triangle_object_textured = create_renderable ( & context - > triangle_mesh_textured , & context - > texture_mesh_material ) ;
if ( triangle_object_textured . attributes . buckets = = 0 ) {
fprintf ( stderr , " failed to create renderable textured triangle object \n " ) ;
return 0 ;
} else {
context - > triangle_object_textured = triangle_object_textured ;
}
return context ;
}
@ -2816,8 +2664,8 @@ VkResult draw_frame(VulkanContext* context) {
}
uint32_t mesh_counts [ ] = { 1 } ;
Object* object s[ ] = { & context - > triangle_ object _textured} ;
result = command_draw _scene( 1 , & context - > texture_mesh_material , ( uint32_t * ) & mesh_counts , ( Object* * ) objects , context - > current_frame , context - > scene_descriptors , context - > swapchain_command_buffers [ context - > current_frame ] , context - > render_pass , context - > swapchain_framebuffers [ image_index ] , context - > swapchain_extent ) ;
Mesh* meshe s[ ] = { & context - > triangle_ mesh _textured} ;
result = record_command_buffer _scene( 1 , & context - > texture_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 ) {
return result ;
}