Split 0a pipeline set into light config set and texture set. Replaced light array ubo with light array storage buffer. But while writing this I realized that my current approach to staging buffer handling is trash, so I will need to rewrite everything I wrote yesterday :(

This commit is contained in:
Андреев Григорий 2026-02-13 18:51:23 +03:00
parent 8cc0b43a5d
commit bca52758cc
9 changed files with 252 additions and 201 deletions

View File

@ -124,10 +124,8 @@ typedef struct {
#define pipeline_0_ubo_point_light_max_count 120
#define pipeline_0_ubo_spotlight_max_count 20
/* This structure will be coupled with point_light and spotlight arrays */
typedef struct {
int point_light_count;
int spotlight_count;
char _padding_1[8];
Pipeline0PointLight point_light_arr[pipeline_0_ubo_point_light_max_count];
Pipeline0Spotlight spotlight_arr[pipeline_0_ubo_spotlight_max_count];
S32 point_light_count;
S32 spotlight_count;
} Pipeline0UBO;

View File

@ -16,7 +16,7 @@ typedef struct {
/* Each generic model has its own descriptor set
* It's because it has its own textures. But it also has copies of references to light UBO
* Because I am to lazy to create two set layouts for generic model pipeline */
VkDescriptorSet p_0a_set_0;
VkDescriptorSet p_0a_set_1;
} AliceGenericMeshMemDependantVkObj;
typedef struct {
@ -85,9 +85,10 @@ void AliceCamVerticalControl_update_direction(
}
typedef struct {
MargaretSubbuf staging;
MargaretSubbuf device_local;
} AlicePipeline0UBO;
MargaretSubbuf num_ubo_staging;
MargaretSubbuf num_ubo_dev_local;
PatriciaBuf point_lights;
} AlicePipline0LightConf;
typedef struct{
vec4 clear_color;
@ -184,26 +185,48 @@ VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_
return render_pass;
}
VkDescriptorSetLayout alice_create_pipline0_desc_set0_layout(VkDevice device) {
VkDescriptorSetLayout pipeline0_desc_set0_layout;
check(vkCreateDescriptorSetLayout(device, &(VkDescriptorSetLayoutCreateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 2,
.pBindings = (VkDescriptorSetLayoutBinding[]){
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
}, {
.binding = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
}
},
}, NULL, &pipeline0_desc_set0_layout) == VK_SUCCESS);
return pipeline0_desc_set0_layout;
}
typedef struct {
VkPipelineLayout pipeline_layout;
VkPipeline pipeline;
VkDescriptorSetLayout descriptor_set_layout;
VkDescriptorSetLayout desc_set_0b1_layout;
} AlicePipeline0a;
void AlicePipeline0a_destroy(VkDevice device, AlicePipeline0a hands) {
vkDestroyPipeline(device, hands.pipeline, NULL);
vkDestroyPipelineLayout(device, hands.pipeline_layout, NULL);
vkDestroyDescriptorSetLayout(device, hands.descriptor_set_layout, NULL);
vkDestroyDescriptorSetLayout(device, hands.desc_set_0b1_layout, NULL);
}
AlicePipeline0a create_graphics_pipeline_0(
VkDevice device, SpanU8 root_dir, VkRenderPass render_pass, uint32_t subpass
AlicePipeline0a create_graphics_pipeline_0a(
VkDevice device, SpanU8 root_dir, VkDescriptorSetLayout pipline0_desc_set0_layout,
VkRenderPass render_pass, uint32_t subpass
) {
VkDescriptorSetLayoutBinding bindings_for_my_descr_set_layout[] = {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
// our shader variable is not an array of descriptors, so this stays 1
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
@ -219,12 +242,6 @@ AlicePipeline0a create_graphics_pipeline_0(
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
{
.binding = 3,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
};
VkDescriptorSetLayoutCreateInfo descriptor_set_layout_crinfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
@ -232,31 +249,27 @@ AlicePipeline0a create_graphics_pipeline_0(
.pBindings = bindings_for_my_descr_set_layout,
};
VkDescriptorSetLayout my_descriptor_set_layout;
if (vkCreateDescriptorSetLayout(device, &descriptor_set_layout_crinfo, NULL, &my_descriptor_set_layout) != VK_SUCCESS)
abortf("vkCreateDescriptorSetLayout");
check(vkCreateDescriptorSetLayout(device, &descriptor_set_layout_crinfo, NULL, &my_descriptor_set_layout) == VK_SUCCESS);
VkPushConstantRange pc_ranges[] = {
{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0, .size = sizeof(mat4)
},
{
}, {
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.offset = sizeof(mat4), .size = sizeof(vec3)
},
};
VkPipelineLayoutCreateInfo layout_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &my_descriptor_set_layout,
.setLayoutCount = 2,
.pSetLayouts = (VkDescriptorSetLayout[]){pipline0_desc_set0_layout, my_descriptor_set_layout},
.pushConstantRangeCount = ARRAY_SIZE(pc_ranges),
.pPushConstantRanges = pc_ranges,
};
VkPipelineLayout pipeline_layout;
if (vkCreatePipelineLayout(device, &layout_crinfo, NULL, &pipeline_layout) != VK_SUCCESS)
abortf("vkCreatePipelineLayout");
check(vkCreatePipelineLayout(device, &layout_crinfo, NULL, &pipeline_layout) == VK_SUCCESS);
VecU8 vert_bin_code = read_file_by_path(VecU8_fmt("%s/gen/l_adele/alice/0gen/vert.spv", root_dir));
@ -267,8 +280,7 @@ AlicePipeline0a create_graphics_pipeline_0(
.binding = 0,
.stride = sizeof(GenericMeshVertex),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
},
{
}, {
.binding = 1,
.stride = sizeof(GenericMeshInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE,
@ -279,23 +291,19 @@ AlicePipeline0a create_graphics_pipeline_0(
.location = 0, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshVertexInc, pos),
},
{
}, {
.location = 1, .binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(GenericMeshVertexInc, tex),
},
{
}, {
.location = 2, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshVertex, norm),
},
{
}, {
.location = 3, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshVertex, tang_U),
},
{
}, {
.location = 4, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshVertex, tang_V),
@ -306,33 +314,27 @@ AlicePipeline0a create_graphics_pipeline_0(
.location = 5, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, x)
},
{
}, {
.location = 6, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, y)
},
{
}, {
.location = 7, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, z)
},
{
}, {
.location = 8, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, w)
},
{
}, {
.location = 9, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshInstance, normal_t) + offsetof(mat3, x)
},
{
}, {
.location = 10, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshInstance, normal_t) + offsetof(mat3, y)
},
{
}, {
.location = 11, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshInstance, normal_t) + offsetof(mat3, z)
@ -347,36 +349,24 @@ AlicePipeline0a create_graphics_pipeline_0(
.vertexAttributeDescriptionCount = ARRAY_SIZE(vertex_attributes), vertex_attributes,
.depthTestEnable = true, .depthWriteEnable = true, .blendEnable = false
});
return (AlicePipeline0a){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout};
return (AlicePipeline0a){.pipeline_layout = pipeline_layout, .pipeline = pipeline,
.desc_set_0b1_layout = my_descriptor_set_layout};
}
typedef struct {
VkPipelineLayout pipeline_layout;
VkPipeline pipeline;
VkDescriptorSetLayout descriptor_set_layout;
} AlicePipeline0b;
void AlicePipeline0b_destroy(VkDevice device, AlicePipeline0b hands) {
vkDestroyPipeline(device, hands.pipeline, NULL);
vkDestroyPipelineLayout(device, hands.pipeline_layout, NULL);
vkDestroyDescriptorSetLayout(device, hands.descriptor_set_layout, NULL);
}
AlicePipeline0b create_graphics_pipeline_0_b(
VkDevice device, SpanU8 root_dir, VkRenderPass render_pass, uint32_t subpass
AlicePipeline0b create_graphics_pipeline_0b(
VkDevice device, SpanU8 root_dir, VkDescriptorSetLayout pipline0_desc_set0_layout,
VkRenderPass render_pass, uint32_t subpass
) {
VkDescriptorSetLayout my_descriptor_set_layout;
check(vkCreateDescriptorSetLayout(device, &(VkDescriptorSetLayoutCreateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.pBindings = (VkDescriptorSetLayoutBinding[]){{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
}},
}, NULL, &my_descriptor_set_layout) == VK_SUCCESS);
VkPushConstantRange pc_ranges[] = {
{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
@ -391,7 +381,7 @@ AlicePipeline0b create_graphics_pipeline_0_b(
check(vkCreatePipelineLayout(device, &(VkPipelineLayoutCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = (VkDescriptorSetLayout[]){my_descriptor_set_layout},
.pSetLayouts = (VkDescriptorSetLayout[]){ pipline0_desc_set0_layout },
.pushConstantRangeCount = ARRAY_SIZE(pc_ranges),
.pPushConstantRanges = pc_ranges,
}, NULL, &pipeline_layout) == VK_SUCCESS);
@ -481,7 +471,7 @@ AlicePipeline0b create_graphics_pipeline_0_b(
.depthTestEnable = true, .depthWriteEnable = true, .blendEnable = false
});
return (AlicePipeline0b){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout};
return (AlicePipeline0b){.pipeline_layout = pipeline_layout, .pipeline = pipeline};
}
VkRenderPass create_render_pass_1(VkDevice logical_device, VkFormat image_format) {
@ -765,7 +755,11 @@ struct Alice {
VkFormat zbuffer_format;
VkFormat IT1_format;
VkRenderPass render_pass_0;
// One descriptor set found in all shaders of pipeline0
VkDescriptorSetLayout pipeline0_desc_set0_layout;
// Features it's own descriptor set layout + built on top of pipeline0_desc_set0_layout
AlicePipeline0a pipeline_hands_0a;
// No personal descriptor set layouts (though it borrows pipeline0_desc_set0_layout)
AlicePipeline0b pipeline_hands_0b;
VkRenderPass render_pass_1;
AlicePipeline1 pipeline_hands_1;
@ -780,6 +774,7 @@ struct Alice {
MargaretImgAllocator dev_local_images;
MargaretBufAllocator dev_local_buffers;
MargaretBufAllocator storage_buffer;
MargaretBufAllocator staging_buffers;
Jane_alice jane; // todo: figure out my own design
@ -788,7 +783,7 @@ struct Alice {
AliceAllSingleUploadBuffers single_upload_buffers;
AliceAllSingleUploadTextures single_upload_textures;
AlicePipeline0UBO pipeline0_ubo;
AlicePipline0LightConf pipeline0_light_conf;
AliceAllMeshesGeneric generic_models;
AliceAllMeshesShiny shiny_models;
AliceCamVerticalControl cam_info;
@ -806,7 +801,7 @@ struct Alice {
VkImageView zbuffer_view;
VkImageView IT1_view;
VkFramebuffer IT1_framebuffer;
VkDescriptorSet descriptor_set_for_pipeline_0b;
VkDescriptorSet descriptor_set_for_pipeline_0;
VkDescriptorSet descriptor_set_for_pipeline_1;
};
@ -906,25 +901,9 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
* this step would have to be repeated */
VkDescriptorSet P = margaret_allocate_descriptor_set(alice->device,
alice->descriptor_pool, alice->pipeline_hands_0a.descriptor_set_layout);
mm->mem_dependant_vk_obj.p_0a_set_0 = P;
alice->descriptor_pool, alice->pipeline_hands_0a.desc_set_0b1_layout);
mm->mem_dependant_vk_obj.p_0a_set_1 = P;
VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0a = {
.buffer = MargaretSubbuf_get_buffer(&alice->pipeline0_ubo.device_local),
.offset = alice->pipeline0_ubo.device_local.start, .range = sizeof(Pipeline0UBO),
};
VkDescriptorImageInfo image_info_for_descriptor_1_in_set_0a = {
.sampler = alice->linear_sampler, .imageView = mm->diffuse_texture->view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkDescriptorImageInfo image_info_for_descriptor_2_in_set_0a = {
.sampler = alice->nearest_sampler, .imageView = mm->normal_texture->view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkDescriptorImageInfo image_info_for_descriptor_3_in_set_0a = {
.sampler = alice->nearest_sampler, .imageView = mm->specular_texture->view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet writes_in_descriptor_set[] = {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@ -932,8 +911,11 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &buffer_info_for_descriptor_0_in_set_0a,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &(VkDescriptorImageInfo){
.sampler = alice->linear_sampler, .imageView = mm->diffuse_texture->view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
},
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@ -942,7 +924,10 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &image_info_for_descriptor_1_in_set_0a,
.pImageInfo = &(VkDescriptorImageInfo){
.sampler = alice->nearest_sampler, .imageView = mm->normal_texture->view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
},
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@ -951,16 +936,10 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &image_info_for_descriptor_2_in_set_0a,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = P,
.dstBinding = 3,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &image_info_for_descriptor_3_in_set_0a,
.pImageInfo = &(VkDescriptorImageInfo){
.sampler = alice->nearest_sampler, .imageView = mm->specular_texture->view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
},
},
};
vkUpdateDescriptorSets(alice->device, ARRAY_SIZE(writes_in_descriptor_set), writes_in_descriptor_set, 0, NULL);
@ -1148,28 +1127,35 @@ void AliceScene__another_frame(Alice* alice) {
mm->instance_attr.count * sizeof(ShinyMeshInstance));
}
}
Pipeline0UBO* mem = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(mem->point_light_count <= pipeline_0_ubo_point_light_max_count);
assert(mem->spotlight_count <= pipeline_0_ubo_spotlight_max_count);
// todo: I will probably replace pipeline0ubo with ubo for length + two readonly storage buffers for light sources
// all of this is basically useless
const MargaretSubbuf* ubo_staging = &alice->pipeline0_ubo.staging;
const MargaretSubbuf* ubo_device_local = &alice->pipeline0_ubo.device_local;
const MargaretSubbuf* ubo_staging = &alice->pipeline0_light_conf.num_ubo_staging;
const MargaretSubbuf* ubo = &alice->pipeline0_light_conf.num_ubo_dev_local;
margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local,
offsetof(Pipeline0UBO, point_light_count), sizeof(int));
margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local,
offsetof(Pipeline0UBO, spotlight_count), sizeof(int));
if (mem->point_light_count) {
margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local,
offsetof(Pipeline0UBO, point_light_arr), sizeof(Pipeline0PointLight) * mem->point_light_count);
const MargaretSubbuf* point_lights_staging = &alice->pipeline0_light_conf.point_lights.staging;
MargaretSubbuf* point_lights = &alice->pipeline0_light_conf.point_lights.device_local;
U64 point_lights_count = alice->pipeline0_light_conf.point_lights.count;
Pipeline0UBO* scene_conf = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_light_conf.num_ubo_staging);
assert((U64)scene_conf->point_light_count == point_lights_count);
assert(point_lights_count * sizeof(Pipeline0PointLight) <= point_lights_staging->len);
margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, ubo_staging, ubo);
if (point_lights_count * sizeof(Pipeline0PointLight) > point_lights->len) {
MargaretBufAllocator_expand_or_free_old(&alice->storage_buffer, point_lights, point_lights_count * sizeof(Pipeline0PointLight));
}
if (mem->spotlight_count) {
margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local,
offsetof(Pipeline0UBO, spotlight_arr), sizeof(Pipeline0Spotlight) * mem->spotlight_count);
assert(point_lights_count * sizeof(Pipeline0PointLight) <= point_lights->len);
if (point_lights_count) {
margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf,
point_lights_staging, point_lights, 0, sizeof(Pipeline0PointLight) * point_lights_count);
}
// maybe we will have spotlights in 2028
// if (mem->spotlight_count) {
// margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local,
// offsetof(Pipeline0UBO, spotlight_arr), sizeof(Pipeline0Spotlight) * mem->spotlight_count);
// }
}
@ -1197,10 +1183,13 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) {
0, sizeof(mat4), &proj_cam_t);
vkCmdPushConstants(alice->rendering_command_buf_0, alice->pipeline_hands_0a.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT,
sizeof(mat4), sizeof(vec3), &alice->cam_info.cam.pos);
vkCmdBindDescriptorSets(
alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0a.pipeline_layout,
0, 1, &alice->descriptor_set_for_pipeline_0, 0, NULL);
for (ListNodeAliceGenericMeshHand* mm_node = alice->generic_models.hands.first; mm_node; mm_node = mm_node->next) {
AliceGenericMeshHand* model = &mm_node->el;
VkDescriptorSet model_indiv_descriptor_set_0 = model->mem_dependant_vk_obj.p_0a_set_0;
VkDescriptorSet descriptor_set1_for_textures = model->mem_dependant_vk_obj.p_0a_set_1;
const MargaretSubbuf* dev_local_vbo = &model->vbo->device_buf;
const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local;
@ -1214,8 +1203,8 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) {
vkCmdBindIndexBuffer(alice->rendering_command_buf_0, MargaretSubbuf_get_buffer(dev_local_ebo), dev_local_ebo->start,
VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(
alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0a.pipeline_layout, 0,
1, &model_indiv_descriptor_set_0, 0, NULL);
alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0a.pipeline_layout,
1, 1, &descriptor_set1_for_textures, 0, NULL);
vkCmdDrawIndexed(alice->rendering_command_buf_0, model->indexes, model->instance_attr.count, 0, 0, 0);
}
@ -1226,8 +1215,9 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) {
vkCmdPushConstants(alice->rendering_command_buf_0, alice->pipeline_hands_0b.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT,
sizeof(mat4), sizeof(vec3), &alice->cam_info.cam.pos);
vkCmdBindDescriptorSets(
alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0b.pipeline_layout, 0,
1, &alice->descriptor_set_for_pipeline_0b, 0, NULL);
alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0b.pipeline_layout,
0, 1, &alice->descriptor_set_for_pipeline_0, 0, NULL);
for (ListNodeAliceShinyMeshHand* mm_node = alice->shiny_models.hands.first; mm_node; mm_node = mm_node->next) {
const AliceShinyMeshHand* model = &mm_node->el;
const MargaretSubbuf* dev_local_vbo = &model->vbo->device_buf;
@ -1310,6 +1300,24 @@ void recreate_swapchain(Alice *alice) {
alice->swfb = new_swfb;
}
/* Helper function for alice_create_mem_dependant_vk_obj: it can update the offset in descr 1 of set 0 for pipeline 0 */
void alice_update_pipe0_set0_descr1(Alice* alice) {
vkUpdateDescriptorSets(alice->device, 1, &(VkWriteDescriptorSet){
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = alice->descriptor_set_for_pipeline_0,
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.pBufferInfo = &(VkDescriptorBufferInfo){
.buffer = MargaretSubbuf_get_buffer(&alice->pipeline0_light_conf.point_lights.device_local),
.offset = alice->pipeline0_light_conf.point_lights.device_local.start,
// .range = alice->pipeline0_light_conf.point_lights.count * sizeof(Pipeline0PointLight),
.range = alice->pipeline0_light_conf.point_lights.device_local.len,
},
}, 0, NULL);
}
/* It creates image views, descriptor sets, framebuffers. But not for generic models.
* If we ever gonna do defragmentation, this step would have to be repeated */
void alice_create_mem_dependant_vk_obj(Alice* alice){
@ -1321,31 +1329,26 @@ void alice_create_mem_dependant_vk_obj(Alice* alice){
alice->IT1_view, alice->zbuffer_view, alice->render_pass_0,
alice->wl.sane_image_extent_limit.width, alice->wl.sane_image_extent_limit.height);
alice->descriptor_set_for_pipeline_0b = margaret_allocate_descriptor_set(
alice->device, alice->descriptor_pool, alice->pipeline_hands_0b.descriptor_set_layout);
alice->descriptor_set_for_pipeline_0 = margaret_allocate_descriptor_set(
alice->device, alice->descriptor_pool, alice->pipeline0_desc_set0_layout);
alice->descriptor_set_for_pipeline_1 = margaret_allocate_descriptor_set(
alice->device, alice->descriptor_pool, alice->pipeline_hands_1.descriptor_set_layout);
// todo: separate set0 and set 1
VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0b = {
.buffer = MargaretSubbuf_get_buffer(&alice->pipeline0_ubo.device_local),
.offset = alice->pipeline0_ubo.device_local.start, .range = sizeof(Pipeline0UBO),
};
VkDescriptorImageInfo image_info_for_descriptor_0_in_set_1 = {
.sampler = alice->nearest_sampler, .imageView = alice->IT1_view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet writes_in_descriptor_sets[] = {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = alice->descriptor_set_for_pipeline_0b,
.dstSet = alice->descriptor_set_for_pipeline_0,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &buffer_info_for_descriptor_0_in_set_0b,
.pBufferInfo = &(VkDescriptorBufferInfo){
.buffer = MargaretSubbuf_get_buffer(&alice->pipeline0_light_conf.num_ubo_dev_local),
.offset = alice->pipeline0_light_conf.num_ubo_dev_local.start, .range = sizeof(Pipeline0UBO),
},
},
/* binding 1 of previous set 0 (pipeline 0) will be updated separately
* Each time you resize point lights vector, you will have to re-update descriptor 1 in set 0:0 */
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = alice->descriptor_set_for_pipeline_1,
@ -1353,10 +1356,14 @@ void alice_create_mem_dependant_vk_obj(Alice* alice){
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &image_info_for_descriptor_0_in_set_1,
.pImageInfo = &(VkDescriptorImageInfo){
.sampler = alice->nearest_sampler, .imageView = alice->IT1_view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
},
},
};
vkUpdateDescriptorSets(alice->device, ARRAY_SIZE(writes_in_descriptor_sets), writes_in_descriptor_sets, 0, NULL);
alice_update_pipe0_set0_descr1(alice);
}
/* Needed for defragmentation of memory */
@ -1827,8 +1834,11 @@ Alice* Alice_new(){
alice->IT1_format = OptionVkFormat_expect(IT1_format_found);
alice->render_pass_0 = create_render_pass_0(alice->device, alice->IT1_format, alice->zbuffer_format);
alice->pipeline_hands_0a = create_graphics_pipeline_0(alice->device, root_dir, alice->render_pass_0, 0);
alice->pipeline_hands_0b = create_graphics_pipeline_0_b(alice->device, root_dir, alice->render_pass_0, 0);
alice->pipeline0_desc_set0_layout = alice_create_pipline0_desc_set0_layout(alice->device);
alice->pipeline_hands_0a = create_graphics_pipeline_0a(alice->device, root_dir, alice->pipeline0_desc_set0_layout,
alice->render_pass_0, 0);
alice->pipeline_hands_0b = create_graphics_pipeline_0b(alice->device, root_dir, alice->pipeline0_desc_set0_layout,
alice->render_pass_0, 0);
alice->render_pass_1 = create_render_pass_1(alice->device, swapchain_details_res.ok.surface_format.format);
alice->pipeline_hands_1 = create_graphics_pipeline_1(alice->device, root_dir, alice->render_pass_1, 0);
@ -1844,7 +1854,7 @@ Alice* Alice_new(){
alice->device_local_mem_mv_command_buf = margaret_allocate_command_buffer(alice->device, alice->command_pool);
// todo: write a descriptor set allocator (in Margaret) that manages dynamic descript or pool allocatrinonsasdasdasd
alice->descriptor_pool = margaret_create_descriptor_set_pool(alice->device, 100, 100, 100);
alice->descriptor_pool = margaret_create_descriptor_set_pool(alice->device, 100, 100, 100, 100);
/* Here we search physical device memory types for the one with host-visible flag and the other with device-local flag */
VkPhysicalDeviceMemoryProperties mem_properties;
@ -1874,14 +1884,18 @@ Alice* Alice_new(){
alice->staging_buffers = MargaretBufAllocator_new(alice->device, alice->physical_device,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
mem_type_id_host_visible_coherent, 3, true, 16);
mem_type_id_host_visible_coherent, 3, true, 16, false);
// todo: inquire about the uniform buffer alignment and storage buffer alignment
alice->dev_local_buffers = MargaretBufAllocator_new(alice->device, alice->physical_device,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ,
mem_type_id_device_local, 6, false, 10000);
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
mem_type_id_device_local, 6, false, 10000, false);
alice->storage_buffer = MargaretBufAllocator_new(alice->device, alice->physical_device,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
/* my temporary solution is to preallocate a lot of memory (obviously) */
mem_type_id_device_local, 5, false, 67000000, true);
alice->dev_local_images = MargaretImgAllocator_new(alice->device, alice->physical_device,
mem_type_id_device_local, 16000000);
@ -1897,10 +1911,14 @@ Alice* Alice_new(){
alice->generic_models = AliceAllMeshesGeneric_new();
alice->shiny_models = AliceAllMeshesShiny_new();
alice->pipeline0_ubo.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO));
alice->pipeline0_ubo.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, sizeof(Pipeline0UBO));
Pipeline0UBO* ubo0 = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
alice->pipeline0_light_conf.num_ubo_staging = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO));
alice->pipeline0_light_conf.num_ubo_dev_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, sizeof(Pipeline0UBO));
Pipeline0UBO* ubo0 = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_light_conf.num_ubo_staging);
ubo0->point_light_count = ubo0->spotlight_count = 0;
alice->pipeline0_light_conf.point_lights.count = 0;
alice->pipeline0_light_conf.point_lights.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 1000);
alice->pipeline0_light_conf.point_lights.device_local = MargaretBufAllocator_alloc(&alice->storage_buffer, 1000);
alice->cam_info = AliceCamVerticalControl_new();
alice->rendering_config = AliceRenderConfig_new();
@ -1935,16 +1953,24 @@ Alice* Alice_new(){
return alice;
}
void Alice_set_point_light_count(Alice* alice, int new_count){
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(new_count <= pipeline_0_ubo_point_light_max_count);
ubo->point_light_count = new_count;
void Alice_set_point_light_count(Alice* alice, U32 new_count){
check(new_count < 1000000);
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_light_conf.num_ubo_staging);
ubo->point_light_count = (S32)new_count;
U64 needed_length = new_count * sizeof(Pipeline0PointLight);
MargaretSubbuf* point_lights_staging = &alice->pipeline0_light_conf.point_lights.staging;
if (needed_length > alice->pipeline0_light_conf.point_lights.staging.len) {
MargaretBufAllocator_expand_or_move_old_host_visible(&alice->staging_buffers, point_lights_staging, needed_length);
alice_update_pipe0_set0_descr1(alice);
}
alice->pipeline0_light_conf.point_lights.count = new_count;
}
void Alice_set_point_light(Alice* alice, int index, Pipeline0PointLight data){
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(index < pipeline_0_ubo_point_light_max_count);
ubo->point_light_arr[index] = data;
void Alice_set_point_light(Alice* alice, U32 index, Pipeline0PointLight data){
assert(index < alice->pipeline0_light_conf.point_lights.count);
Pipeline0PointLight* arr = (Pipeline0PointLight*)MargaretSubbuf_get_mapped(&
alice->pipeline0_light_conf.point_lights.staging);
arr[index] = data;
}
/* This function actually consumes alice handler. Alice must not be used after */

View File

@ -103,8 +103,8 @@ void LucyRenderer_draw_char_glyph(LucyRenderer* self, vec4 color, ivec2 pos, Luc
U64 needed_vbo_length = (self->glyphs_count + 1) * sizeof(LucyRenderInstance);
if (self->staging_vbo.len < needed_vbo_length) {
printf("LucyRenderer Staging Buffer: Gotta replace %lu with %lu\n",
self->staging_vbo.len, needed_vbo_length);
//printf("LucyRenderer Staging Buffer: Gotta replace %lu with %lu\n",
// self->staging_vbo.len, needed_vbo_length);
MargaretBufAllocator_expand_or_move_old_host_visible(
self->ve.staging_buffers, &self->staging_vbo, needed_vbo_length);
}

View File

@ -61,6 +61,7 @@ typedef struct {
U8 memory_type_id;
U8 alignment_exp;
bool host_visible;
bool ban_non_envisaged_blocks;
} MargaretBufAllocator;
@ -126,13 +127,16 @@ void MargaretBufAllocator__add_block(MargaretBufAllocator* self, U64 capacity){
MargaretBufAllocator MargaretBufAllocator_new(
VkDevice device, VkPhysicalDevice physical_device,
VkBufferUsageFlags usage, U8 memory_type_id, U8 alignment_exp, bool host_visible, U64 initial_block_size
VkBufferUsageFlags usage,
U8 memory_type_id, U8 alignment_exp, bool host_visible,
U64 initial_block_size, bool ban_non_envisaged_blocks
){
MargaretBufAllocator self = {
.blocks = ListMargaretBufAllocatorOneBlock_new(),
.mem_free_space = BufRBTreeByLen_SetMargaretBAFreeSegment_new_reserved(1),
.device = device, .physical_device = physical_device, .usage = usage, .memory_type_id = memory_type_id,
.alignment_exp = alignment_exp, .host_visible = host_visible
.alignment_exp = alignment_exp, .host_visible = host_visible,
.ban_non_envisaged_blocks = ban_non_envisaged_blocks,
};
MargaretBufAllocator__add_block(&self, initial_block_size);
MargaretBufAllocator__insert_gap(&self, &self.blocks.first->el, 0, initial_block_size);
@ -245,7 +249,10 @@ void MargaretBufAllocator_free(MargaretBufAllocator* self, MargaretSubbuf alloca
}
NODISCARD MargaretSubbuf MargaretBufAllocator_alloc(MargaretBufAllocator* self, U64 req_size){
// MargaretBufAllocator_debug(self);
/* todo: remove debug */
if (self->ban_non_envisaged_blocks) {
MargaretBufAllocator_debug(self);
}
req_size = margaret_bump_buffer_size_to_alignment(req_size, self->alignment_exp);
VkPhysicalDeviceMaintenance3Properties maintenance3_properties = {
@ -261,6 +268,8 @@ NODISCARD MargaretSubbuf MargaretBufAllocator_alloc(MargaretBufAllocator* self,
OptionMargaretBAFreeSegment free_gap = MargaretBufAllocator__search_gap(self, req_size);
if (free_gap.variant == Option_None) {
assert(self->blocks.first != NULL);
if (self->ban_non_envisaged_blocks)
abortf("Exceeded the size of the initial memory block in a buffer allocator that bans additional blocks\n");
U64 pitch = self->blocks.first->el.capacity;
// Old blocks remain intact
U64 new_capacity = MAX_U64(req_size, MIN_U64(2 * pitch, maintenance3_properties.maxMemoryAllocationSize));
@ -274,7 +283,10 @@ NODISCARD MargaretSubbuf MargaretBufAllocator_alloc(MargaretBufAllocator* self,
return (MargaretSubbuf){.block = &self->blocks.first->el, 0, req_size};
}
MargaretBufAllocator__put_buf_to_a_gap(self, free_gap.some, req_size);
// MargaretBufAllocator_debug(self);
/* todo: remove debug */
if (self->ban_non_envisaged_blocks) {
MargaretBufAllocator_debug(self);
}
return (MargaretSubbuf){.block = free_gap.some.block, .start = free_gap.some.start, req_size};
}
@ -305,7 +317,10 @@ NODISCARD MargaretSubbuf MargaretBufAllocator_expand(
if (allocation->start + bigger_size > right_free_space.start + right_free_space.len){
return MargaretBufAllocator_alloc(self, bigger_size);
}
// MargaretBufAllocator_debug(self);
/* todo: remove debug */
if (self->ban_non_envisaged_blocks) {
MargaretBufAllocator_debug(self);
}
MargaretBufAllocator__erase_gap(self, allocation->block, right_free_space.start, right_free_space.len);
MargaretBufAllocator__insert_gap(self, allocation->block,
allocation->start + bigger_size,

View File

@ -337,7 +337,7 @@ void MargaretImgAllocator__insert_gap(MargaretImgAllocator* self, U64 block_id,
void MargaretImgAllocator__add_block(MargaretImgAllocator* self, U64 capacity){
VkDeviceMemory memory;
printf("DEBUG MargaretImgAllocator: allocating block of size %lu\n", capacity);
// printf("DEBUG MargaretImgAllocator: allocating block of size %lu\n", capacity);
check(vkAllocateMemory(self->device, &(VkMemoryAllocateInfo){
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = capacity, .memoryTypeIndex = self->memory_type_id

View File

@ -965,9 +965,11 @@ VkSampler margaret_create_sampler(VkPhysicalDevice physical_device, VkDevice dev
}
VkDescriptorPool margaret_create_descriptor_set_pool(
VkDevice device, uint32_t ubo_descriptor_count, uint32_t image_sampler_descriptor_count, uint32_t max_sets
VkDevice device,
uint32_t ubo_descriptor_count, uint32_t image_sampler_descriptor_count, uint32_t storage_buffer_descriptor_count,
uint32_t max_sets
) {
VkDescriptorPoolSize sizes[2];
VkDescriptorPoolSize sizes[3];
int sizes_c = 0;
if (ubo_descriptor_count > 0) {
sizes[sizes_c] = (VkDescriptorPoolSize){
@ -983,6 +985,13 @@ VkDescriptorPool margaret_create_descriptor_set_pool(
};
sizes_c++;
}
if (storage_buffer_descriptor_count > 0) {
sizes[sizes_c] = (VkDescriptorPoolSize){
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = storage_buffer_descriptor_count
};
sizes_c++;
}
VkDescriptorPool descriptor_pool;
check(vkCreateDescriptorPool(device, &(VkDescriptorPoolCreateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,

View File

@ -256,8 +256,15 @@ void main_h_on_another_frame(void* data, float fl){
.model_t = RigidBodyState_get_tran_mat_of_mesh(&st->ROA_state),
});
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st->alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= st->LS_state.len);
// Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st->alice->pipeline0_ubo.staging);
// assert(pipeline_0_ubo_point_light_max_count >= st->LS_state.len);
if (st->LS_state.len > alice->pipeline0_light_conf.point_lights.count) {
Alice_set_point_light_count(alice, st->LS_state.len);
}
if (st->LS_state.len + st->bullets_stuck_on_ROA.len > st->LS_mesh->el.instance_attr.count) {
AliceShinyMeshHand_resize_instance_arr(alice, &st->LS_mesh->el, st->LS_state.len + st->bullets_stuck_on_ROA.len);
}
for (size_t i = 0; i < st->LS_state.len; i++) {
LightSourceState* ls = &st->LS_state.buf[i];
@ -265,11 +272,7 @@ void main_h_on_another_frame(void* data, float fl){
.color_on = ls->color,
.model_t = marie_translation_mat4(ls->pos),
});
ubo->point_light_arr[i] = (Pipeline0PointLight){
.pos = ls->pos, .color = vec3_mul_scal(ls->color, 21)};
}
if (st->LS_state.len + st->bullets_stuck_on_ROA.len > st->LS_mesh->el.instance_attr.count) {
AliceShinyMeshHand_resize_instance_arr(alice, &st->LS_mesh->el, st->LS_state.len + st->bullets_stuck_on_ROA.len);
Alice_set_point_light(alice, i, (Pipeline0PointLight){.pos = ls->pos, .color = vec3_mul_scal(ls->color, 21)});
}
for (size_t i = 0; i < st->bullets_stuck_on_ROA.len; i++) {
@ -387,10 +390,6 @@ void run_app(){
}
AliceShinyMeshHand_resize_instance_arr(st.alice, &st.LS_mesh->el, st.LS_state.len);
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st.alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= st.LS_state.len);
ubo->point_light_count = (int)st.LS_state.len;
ubo->spotlight_count = 0;
st.bullet_config = (BulletConfig){.mass = 0.01f, .velocity = 1000};
st.misses_count = 0;

View File

@ -9,31 +9,33 @@ layout(location = 4) in vec3 pos;
/* Right now all in set 0 */
layout(location = 0) out vec4 fin_color;
/* Yes, even these guys */
layout(binding = 1) uniform sampler2D color_tex;
layout(binding = 2) uniform sampler2D normal_map;
layout(binding = 3) uniform sampler2D specular_map;
layout(set = 1, binding = 0) uniform sampler2D color_tex;
layout(set = 1, binding = 1) uniform sampler2D normal_map;
layout(set = 1, binding = 2) uniform sampler2D specular_map;
layout(push_constant, std430) uniform pc {
layout(offset = 64) vec3 camera_pos;
};
struct Pipeline0PointLight {
struct PointLight {
vec3 pos;
vec3 color;
};
struct Pipeline0Spotlight {
struct Spotlight {
vec3 pos;
vec3 dir;
vec3 color;
float range;
};
layout(std140, binding = 0) uniform Pipeline0UBO {
layout (std140, set = 0, binding = 0) uniform NumUBO {
int point_light_count;
int spotlight_count;
Pipeline0PointLight point_light_arr[120];
Pipeline0Spotlight spotlight_arr [20];
};
layout (std430, set = 0, binding = 1) readonly buffer PointLightsArray {
PointLight point_light_arr[];
};
float get_intensity(float dist){
@ -47,7 +49,7 @@ void main(){
vec3 diffuse_illumination = vec3(0);
vec3 specular_illumination = vec3(0);
for (int i = 0; i < point_light_count; i++) {
Pipeline0PointLight lamp = point_light_arr[i];
PointLight lamp = point_light_arr[i];
vec3 to_light = -pos + lamp.pos;
float dist = length(to_light);
vec3 U = to_light / dist;
@ -58,9 +60,9 @@ void main(){
vec3 B = to_cam / dist_to_cam;
specular_illumination += get_intensity(dist) * pow(max(0, dot(A, B)), 32) * lamp.color;
}
for (int i = 0; i < spotlight_count; i++) {
Pipeline0Spotlight lamp = spotlight_arr[i];
}
//for (int i = 0; i < spotlight_count; i++) {
// Pipeline0Spotlight lamp = spotlight_arr[i];
//}
vec3 natural_color = texture(color_tex, tex).xyz;
float specular_c = texture(specular_map, tex).x;
vec3 color = natural_color * diffuse_illumination + specular_c * specular_illumination;

View File

@ -11,23 +11,25 @@ layout(push_constant, std430) uniform pc {
layout(offset = 64) vec3 camera_pos;
};
struct Pipeline0PointLight {
struct PointLight {
vec3 pos;
vec3 color;
};
struct Pipeline0Spotlight {
struct Spotlight {
vec3 pos;
vec3 dir;
vec3 color;
float range;
};
layout(std140, binding = 0) uniform Pipeline0UBO {
layout (std140, set = 0, binding = 0) uniform NumUBO {
int point_light_count;
int spotlight_count;
Pipeline0PointLight point_light_arr[120];
Pipeline0Spotlight spotlight_arr [20];
};
layout (std430, set = 0, binding = 1) readonly buffer PointLightsArray {
PointLight point_light_arr[];
};
float get_intensity(float dist){
@ -38,7 +40,7 @@ void main(){
vec3 diffuse_illumination = vec3(0);
vec3 specular_illumination = vec3(0);
for (int i = 0; i < point_light_count; i++) {
Pipeline0PointLight lamp = point_light_arr[i];
PointLight lamp = point_light_arr[i];
vec3 to_light = -pos + lamp.pos;
float dist = length(to_light);
vec3 U = to_light / dist;
@ -47,9 +49,9 @@ void main(){
vec3 B = normalize(-pos+camera_pos);
// specular_illumination += get_intensity(dist) * pow(max(0, dot(A, B)), 256) * lamp.color;
}
for (int i = 0; i < spotlight_count; i++) {
Pipeline0Spotlight lamp = spotlight_arr[i];
}
// for (int i = 0; i < spotlight_count; i++) {
// Spotlight lamp = spotlight_arr[i];
// }
vec3 color = color_off * diffuse_illumination + (0.05 + 0.45 * length(color_off)) * specular_illumination + color_on;
fin_color = vec4(color, 1);
}