Compare commits
No commits in common. "5b8ecd80207b59eabe831b0a07fed4dbd9685e3f" and "1fbd4f041371ce2a49c106c745675b025b584c37" have entirely different histories.
5b8ecd8020
...
1fbd4f0413
2
Makefile
2
Makefile
@ -9,7 +9,7 @@ HEADERS_src_l1_5 = $(HEADERS_gen_l1) $(call find_headers,l1_5)
|
||||
#HEADERS_gen_l1_5 := $(HEADERS_src_l1_5) gen/l1_5/dorothy.txt
|
||||
HEADERS_gen_l1_5 := gen/l1_5/dorothy.txt
|
||||
|
||||
ASSETS_src_l_adele = $(call find_assets,l_adele)
|
||||
ASSETS_src_l_adele = $($call find_assets,l_adele)
|
||||
ASSETS_gen_l_adele = gen/l_adele/dorothy.txt
|
||||
|
||||
HEADERS_src_l2 := $(HEADERS_gen_l1_5) $(call find_headers,l2)
|
||||
|
||||
@ -10,11 +10,6 @@ void generate_code_for_alice_on_l1(){
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("GenericMeshVertexInc"), true, true);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("ShinyMeshVertexInc"), true, true);
|
||||
|
||||
/* Helpful utils for sticking your butt into rendering mainloop (transferring stuff to device local
|
||||
* memory at the right time) */
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("RefAliceBufferUplOnce"), true, false);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("RefAliceTextureUplOnce"), true, false);
|
||||
|
||||
/* Engine stuff */
|
||||
// todo: yes, maybe right now it is not primitive but I surely will make it primitive someday. Right now I don't care
|
||||
generate_List_templ_inst_eve_header(l, ns, (list_instantiation_op){
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
#include "model_file.h"
|
||||
#include "../../l1/marie/geom_alg_utils.h"
|
||||
#include "../margaret/vulkan_utils.h"
|
||||
#include "transfer_in_mainloop.h"
|
||||
#include "../lucy/glyph_render.h"
|
||||
|
||||
typedef struct {
|
||||
@ -13,6 +12,9 @@ typedef struct {
|
||||
} PatriciaBuf;
|
||||
|
||||
typedef struct {
|
||||
VkImageView diffuse_view;
|
||||
VkImageView normal_view;
|
||||
VkImageView specular_view;
|
||||
/* 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 */
|
||||
@ -21,21 +23,28 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
size_t indexes;
|
||||
// Option<MargaretSubbuf>
|
||||
MargaretSubbuf staging_vbo;
|
||||
// Option<MargaretSubbuf>
|
||||
MargaretSubbuf staging_ebo;
|
||||
|
||||
// todo: replace TextureDataXXX with MargaretPngPromises
|
||||
TextureDataR8G8B8A8 pixels_diffuse;
|
||||
TextureDataR8G8B8A8 pixels_normal;
|
||||
TextureDataR8 pixels_specular;
|
||||
|
||||
AliceBufferUplOnce* vbo;
|
||||
AliceBufferUplOnce* ebo;
|
||||
|
||||
AliceTextureUplOnce* diffuse_texture;
|
||||
AliceTextureUplOnce* normal_texture;
|
||||
AliceTextureUplOnce* specular_texture;
|
||||
MargaretSubbuf staging_diffuse_tex_buf;
|
||||
MargaretSubbuf staging_normal_tex_buf;
|
||||
MargaretSubbuf staging_specular_tex_buf;
|
||||
|
||||
MargaretSubbuf vbo;
|
||||
MargaretSubbuf ebo;
|
||||
PatriciaBuf instance_attr;
|
||||
|
||||
MargaretImg diffuse_texture;
|
||||
MargaretImg normal_texture;
|
||||
MargaretImg specular_texture;
|
||||
|
||||
AliceGenericMeshMemDependantVkObj mem_dependant_vk_obj;
|
||||
|
||||
bool scheduled_for_deletion;
|
||||
@ -46,8 +55,11 @@ typedef struct {
|
||||
typedef struct {
|
||||
size_t indexes;
|
||||
|
||||
AliceBufferUplOnce* vbo;
|
||||
AliceBufferUplOnce* ebo;
|
||||
MargaretSubbuf staging_vbo;
|
||||
MargaretSubbuf staging_ebo;
|
||||
|
||||
MargaretSubbuf vbo;
|
||||
MargaretSubbuf ebo;
|
||||
PatriciaBuf instance_attr;
|
||||
|
||||
bool scheduled_for_deletion;
|
||||
@ -724,12 +736,17 @@ typedef struct ListNodeAliceGenericMeshHand* RefListNodeAliceGenericMeshHand;
|
||||
|
||||
typedef struct {
|
||||
ListAliceGenericMeshHand hands;
|
||||
/* Familiar pattern. Todo: move familiar pattern to l1 codegen. 2 matches so far */
|
||||
VecRefListNodeAliceGenericMeshHand to_be_freed_of_old_staging_next_cycle;
|
||||
VecRefListNodeAliceGenericMeshHand to_be_copied_to_device_next_cycle;
|
||||
VecRefListNodeAliceGenericMeshHand to_be_deleted;
|
||||
} AliceAllMeshesGeneric;
|
||||
|
||||
AliceAllMeshesGeneric AliceAllMeshesGeneric_new(){
|
||||
return (AliceAllMeshesGeneric){
|
||||
.hands = ListAliceGenericMeshHand_new(),
|
||||
.to_be_freed_of_old_staging_next_cycle = VecRefListNodeAliceGenericMeshHand_new(),
|
||||
.to_be_copied_to_device_next_cycle = VecRefListNodeAliceGenericMeshHand_new(),
|
||||
.to_be_deleted = VecRefListNodeAliceGenericMeshHand_new(),
|
||||
};
|
||||
}
|
||||
@ -740,12 +757,16 @@ typedef struct ListNodeAliceShinyMeshHand* RefListNodeAliceShinyMeshHand;
|
||||
typedef struct {
|
||||
ListAliceShinyMeshHand hands;
|
||||
/* Ah */
|
||||
VecRefListNodeAliceShinyMeshHand to_be_freed_of_old_staging_next_cycle;
|
||||
VecRefListNodeAliceShinyMeshHand to_be_copied_to_device_next_cycle;
|
||||
VecRefListNodeAliceShinyMeshHand to_be_deleted;
|
||||
} AliceAllMeshesShiny;
|
||||
|
||||
AliceAllMeshesShiny AliceAllMeshesShiny_new(){
|
||||
return (AliceAllMeshesShiny){
|
||||
.hands = ListAliceShinyMeshHand_new(),
|
||||
.to_be_freed_of_old_staging_next_cycle = VecRefListNodeAliceShinyMeshHand_new(),
|
||||
.to_be_copied_to_device_next_cycle = VecRefListNodeAliceShinyMeshHand_new(),
|
||||
.to_be_deleted = VecRefListNodeAliceShinyMeshHand_new(),
|
||||
};
|
||||
}
|
||||
@ -785,9 +806,6 @@ struct Alice {
|
||||
Jane_alice jane; // todo: figure out my own design
|
||||
MargaretSwapchainBundle swfb;
|
||||
|
||||
AliceAllSingleUploadBuffers single_upload_buffers;
|
||||
AliceAllSingleUploadTextures single_upload_textures;
|
||||
|
||||
AlicePipeline0UBO pipeline0_ubo;
|
||||
AliceAllMeshesGeneric generic_models;
|
||||
AliceAllMeshesShiny shiny_models;
|
||||
@ -811,8 +829,7 @@ struct Alice {
|
||||
};
|
||||
|
||||
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const GenericMeshTopology* topology,
|
||||
AliceGenericMeshTexturePaths t_paths
|
||||
){
|
||||
AliceGenericMeshTexturePaths t_paths){
|
||||
|
||||
ListNodeAliceGenericMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceGenericMeshHand));
|
||||
AliceGenericMeshHand* mm = &mm_node->el;
|
||||
@ -821,6 +838,11 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 200);
|
||||
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 200);
|
||||
|
||||
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
topology->vertices.len * sizeof(GenericMeshVertex));
|
||||
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
topology->indexes.len * sizeof(U32));
|
||||
|
||||
// todo: change this, I don't like this at all :(
|
||||
mm->pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.diffuse_texture_path));
|
||||
mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.normal_texture_path));
|
||||
@ -829,36 +851,38 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
VecU8_drop(t_paths.normal_texture_path);
|
||||
VecU8_drop(t_paths.specular_texture_path);
|
||||
|
||||
mm->vbo = AliceAllSingleUploadBuffers_register_new(&alice->single_upload_buffers,
|
||||
topology->vertices.len * sizeof(GenericMeshVertex),
|
||||
&alice->staging_buffers, &alice->dev_local_buffers);
|
||||
mm->ebo = AliceAllSingleUploadBuffers_register_new(&alice->single_upload_buffers,
|
||||
topology->indexes.len * sizeof(U32),
|
||||
&alice->staging_buffers, &alice->dev_local_buffers);
|
||||
mm->staging_diffuse_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
mm->pixels_diffuse.pixels.len * sizeof(cvec4));
|
||||
mm->staging_normal_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
mm->pixels_normal.pixels.len * sizeof(cvec4));
|
||||
mm->staging_specular_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
mm->pixels_specular.pixels.len * sizeof(U8));
|
||||
|
||||
mm->diffuse_texture = AliceAllSingleUploadTextures_register_new(&alice->single_upload_textures,
|
||||
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
|
||||
topology->vertices.len * sizeof(GenericMeshVertex));
|
||||
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
|
||||
topology->indexes.len * sizeof(U32));
|
||||
|
||||
mm->diffuse_texture = MargaretImgAllocator_alloc(&alice->dev_local_images,
|
||||
mm->pixels_diffuse.width, mm->pixels_diffuse.height,
|
||||
sizeof(cvec4), VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
&alice->staging_buffers, &alice->dev_local_images);
|
||||
mm->normal_texture = AliceAllSingleUploadTextures_register_new(&alice->single_upload_textures,
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
mm->normal_texture = MargaretImgAllocator_alloc(&alice->dev_local_images,
|
||||
mm->pixels_normal.width, mm->pixels_normal.height,
|
||||
sizeof(cvec4), VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
&alice->staging_buffers, &alice->dev_local_images);
|
||||
mm->specular_texture = AliceAllSingleUploadTextures_register_new(&alice->single_upload_textures,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
mm->specular_texture = MargaretImgAllocator_alloc(&alice->dev_local_images,
|
||||
mm->pixels_specular.width, mm->pixels_specular.height,
|
||||
sizeof(U8), VK_FORMAT_R8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
&alice->staging_buffers, &alice->dev_local_images);
|
||||
VK_FORMAT_R8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
|
||||
mm->scheduled_for_deletion = false;
|
||||
|
||||
/* We allocated enough memory, but now it's time to actually fill staging buffers */
|
||||
/* Filling staging VBO */
|
||||
assert(mm->vbo->staging.len >= topology->vertices.len * sizeof(GenericMeshVertex));
|
||||
assert(mm->vbo->device_buf.len >= topology->vertices.len * sizeof(GenericMeshVertex));
|
||||
GenericMeshVertex* staging_vbo = (GenericMeshVertex*)AliceBufferUplOnce_get_mapped_staging(mm->vbo);
|
||||
/* Filleing staging VBO */
|
||||
assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex));
|
||||
assert(mm->vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex));
|
||||
GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
|
||||
for (U64 i = 0; i < topology->vertices.len; i++) {
|
||||
staging_vbo[i].base = topology->vertices.buf[i];
|
||||
}
|
||||
@ -888,47 +912,53 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
/* Filling EBO is easy */
|
||||
assert(topology->indexes.len == mm->indexes);
|
||||
size_t ebo_len = topology->indexes.len * sizeof(U32);
|
||||
assert(mm->ebo->staging.len >= ebo_len);
|
||||
U32* staging_ebo = (U32*)AliceBufferUplOnce_get_mapped_staging(mm->ebo);
|
||||
assert(mm->ebo.len >= ebo_len);
|
||||
U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo);
|
||||
memcpy(staging_ebo, topology->indexes.buf, ebo_len);
|
||||
/* Filling staging textures from memory pixel data */
|
||||
/* todo: do it immediately ON THE READ */
|
||||
memcpy(AliceTextureUplOnce_get_mapped_staging(mm->diffuse_texture), mm->pixels_diffuse.pixels.buf,
|
||||
memcpy(MargaretSubbuf_get_mapped(&mm->staging_diffuse_tex_buf), mm->pixels_diffuse.pixels.buf,
|
||||
TextureDataR8G8B8A8_get_size_in_bytes(&mm->pixels_diffuse));
|
||||
memcpy(AliceTextureUplOnce_get_mapped_staging(mm->normal_texture), mm->pixels_normal.pixels.buf,
|
||||
memcpy(MargaretSubbuf_get_mapped(&mm->staging_normal_tex_buf), mm->pixels_normal.pixels.buf,
|
||||
TextureDataR8G8B8A8_get_size_in_bytes(&mm->pixels_normal));
|
||||
memcpy(AliceTextureUplOnce_get_mapped_staging(mm->specular_texture), mm->pixels_specular.pixels.buf,
|
||||
memcpy(MargaretSubbuf_get_mapped(&mm->staging_specular_tex_buf), mm->pixels_specular.pixels.buf,
|
||||
TextureDataR8_get_size_in_bytes(&mm->pixels_specular));
|
||||
// todo: that is about time when we can delete mm->pixels_* buffers. They are still wasting space out there
|
||||
// todo: BUt I won't do it, because I chose inplace texture reading (from png)
|
||||
|
||||
/* But now we are filling AliceGenericMeshMemDependantVkObj. If we ever gonna do defragmentation,
|
||||
* 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;
|
||||
AliceGenericMeshMemDependantVkObj P = (AliceGenericMeshMemDependantVkObj){
|
||||
.diffuse_view = margaret_create_view_for_image(alice->device, mm->diffuse_texture.a.image,
|
||||
VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
.normal_view = margaret_create_view_for_image(alice->device, mm->normal_texture.a.image,
|
||||
VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
.specular_view = margaret_create_view_for_image(alice->device, mm->specular_texture.a.image,
|
||||
VK_FORMAT_R8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
.p_0a_set_0 = margaret_allocate_descriptor_set(alice->device,
|
||||
alice->descriptor_pool, alice->pipeline_hands_0a.descriptor_set_layout),
|
||||
};
|
||||
mm->mem_dependant_vk_obj = 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,
|
||||
.sampler = alice->linear_sampler, .imageView = P.diffuse_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,
|
||||
.sampler = alice->nearest_sampler, .imageView = P.normal_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,
|
||||
.sampler = alice->nearest_sampler, .imageView = P.specular_view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
};
|
||||
VkWriteDescriptorSet writes_in_descriptor_set[] = {
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = P,
|
||||
.dstSet = P.p_0a_set_0,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
@ -937,7 +967,7 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = P,
|
||||
.dstSet = P.p_0a_set_0,
|
||||
.dstBinding = 1,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
@ -946,7 +976,7 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = P,
|
||||
.dstSet = P.p_0a_set_0,
|
||||
.dstBinding = 2,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
@ -955,7 +985,7 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = P,
|
||||
.dstSet = P.p_0a_set_0,
|
||||
.dstBinding = 3,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
@ -966,10 +996,12 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic
|
||||
vkUpdateDescriptorSets(alice->device, ARRAY_SIZE(writes_in_descriptor_set), writes_in_descriptor_set, 0, NULL);
|
||||
|
||||
ListAliceGenericMeshHand_insert_node(&alice->generic_models.hands, mm_node);
|
||||
VecRefListNodeAliceGenericMeshHand_append(&alice->generic_models.to_be_copied_to_device_next_cycle, mm_node);
|
||||
return mm_node;
|
||||
}
|
||||
|
||||
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTopology* topology){
|
||||
|
||||
ListNodeAliceShinyMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceShinyMeshHand));
|
||||
AliceShinyMeshHand* mm = &mm_node->el;
|
||||
|
||||
@ -979,18 +1011,23 @@ ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTo
|
||||
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 128);
|
||||
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 128);
|
||||
|
||||
mm->vbo = AliceAllSingleUploadBuffers_register_new(&alice->single_upload_buffers,
|
||||
topology->vertices.len * sizeof(ShinyMeshVertex),
|
||||
&alice->staging_buffers, &alice->dev_local_buffers);
|
||||
mm->ebo = AliceAllSingleUploadBuffers_register_new(&alice->single_upload_buffers,
|
||||
topology->indexes.len * sizeof(U32),
|
||||
&alice->staging_buffers, &alice->dev_local_buffers);
|
||||
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
topology->vertices.len * sizeof(ShinyMeshVertex));
|
||||
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
|
||||
topology->indexes.len * sizeof(U32));
|
||||
|
||||
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
|
||||
topology->vertices.len * sizeof(ShinyMeshVertex));
|
||||
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
|
||||
topology->indexes.len * sizeof(U32));
|
||||
|
||||
ListAliceShinyMeshHand_insert_node(&alice->shiny_models.hands, mm_node);
|
||||
VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_copied_to_device_next_cycle, mm_node);
|
||||
/* We allocated enough memory, now it's time to actually fill staging buffers */
|
||||
/* And we start by filling staging VBO */
|
||||
assert(mm->vbo->staging.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
|
||||
assert(mm->vbo->device_buf.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
|
||||
ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)AliceBufferUplOnce_get_mapped_staging(mm->vbo);
|
||||
assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
|
||||
assert(mm->vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
|
||||
ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
|
||||
for (U64 i = 0; i < topology->vertices.len; i++) {
|
||||
staging_vbo[i].base = topology->vertices.buf[i];
|
||||
}
|
||||
@ -1005,43 +1042,21 @@ ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTo
|
||||
vec3 norm = vec3_normalize(vec3_cross(vec3_minus_vec3(p1, p0), vec3_minus_vec3(p2, p0)));
|
||||
staging_vbo[v0].normal = staging_vbo[v1].normal = staging_vbo[v2].normal = norm;
|
||||
}
|
||||
|
||||
/* Filling staging EBO is super-duper easy */
|
||||
|
||||
assert(topology->indexes.len == mm->indexes);
|
||||
size_t ebo_len = topology->indexes.len * sizeof(U32);
|
||||
assert(mm->ebo->staging.len >= ebo_len);
|
||||
U32* staging_ebo = (U32*)AliceBufferUplOnce_get_mapped_staging(mm->ebo);
|
||||
assert(mm->ebo.len >= ebo_len);
|
||||
U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo);
|
||||
memcpy(staging_ebo, topology->indexes.buf, ebo_len);
|
||||
|
||||
ListAliceShinyMeshHand_insert_node(&alice->shiny_models.hands, mm_node);
|
||||
return mm_node;
|
||||
}
|
||||
|
||||
|
||||
void Alice_delete_generic_mesh(Alice* alice, ListNodeAliceGenericMeshHand* hand) {
|
||||
AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.vbo);
|
||||
AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.ebo);
|
||||
AliceAllSingleUploadTextures_delete(&alice->single_upload_textures, hand->el.diffuse_texture);
|
||||
AliceAllSingleUploadTextures_delete(&alice->single_upload_textures, hand->el.normal_texture);
|
||||
AliceAllSingleUploadTextures_delete(&alice->single_upload_textures, hand->el.specular_texture);
|
||||
hand->el.normal_texture = hand->el.normal_texture = hand->el.specular_texture = NULL;
|
||||
hand->el.vbo = hand->el.ebo = NULL;
|
||||
VecRefListNodeAliceGenericMeshHand_append(&alice->generic_models.to_be_deleted, hand);
|
||||
}
|
||||
|
||||
void Alice_delete_shiny_mesh(Alice* alice, ListNodeAliceShinyMeshHand* hand) {
|
||||
AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.vbo);
|
||||
AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.ebo);
|
||||
hand->el.vbo = hand->el.ebo = NULL;
|
||||
VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_deleted, hand);
|
||||
}
|
||||
|
||||
|
||||
void AliceGenericMeshHand_resize_instance_arr(Alice* alice, AliceGenericMeshHand* self, U64 new_count){
|
||||
U64 needed_length = new_count * sizeof(GenericMeshInstance);
|
||||
if (self->instance_attr.staging.len < needed_length) {
|
||||
printf("Alice generic model instance staging Buffer: Gotta replace %lu with %lu\n",
|
||||
self->instance_attr.staging.len, needed_length);
|
||||
self->staging_vbo.len, needed_length);
|
||||
MargaretBufAllocator_expand_or_move_old_host_visible(
|
||||
&alice->staging_buffers, &self->instance_attr.staging, needed_length);
|
||||
}
|
||||
@ -1079,34 +1094,108 @@ void AliceShinyMeshHand_set_inst(AliceShinyMeshHand* self, size_t instance, Shin
|
||||
tr_inv.x.z, tr_inv.y.z, tr_inv.z.z );
|
||||
}
|
||||
|
||||
void AliceAllMeshesGeneric__resolve_on_another_frame(Alice* alice, AliceAllMeshesGeneric* self){
|
||||
void AliceAllMeshesGeneric__resolve_mesh_creation(Alice* alice, AliceAllMeshesGeneric* self){
|
||||
for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) {
|
||||
AliceGenericMeshHand* mm = &self->to_be_freed_of_old_staging_next_cycle.buf[i]->el;
|
||||
assert(mm->staging_vbo.len != 0);
|
||||
assert(mm->staging_ebo.len != 0);
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo);
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo);
|
||||
mm->staging_vbo.len = 0;
|
||||
mm->staging_ebo.len = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) {
|
||||
ListNodeAliceGenericMeshHand* mm_node = self->to_be_copied_to_device_next_cycle.buf[i];
|
||||
AliceGenericMeshHand* mm = &mm_node->el;
|
||||
assert(mm->staging_vbo.len != 0);
|
||||
assert(mm->staging_ebo.len != 0);
|
||||
if (mm->scheduled_for_deletion)
|
||||
continue;
|
||||
margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_vbo, &mm->vbo);
|
||||
margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_ebo, &mm->ebo);
|
||||
margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf,
|
||||
&mm->staging_diffuse_tex_buf, &mm->diffuse_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf,
|
||||
&mm->staging_normal_tex_buf, &mm->normal_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf,
|
||||
&mm->staging_specular_tex_buf, &mm->specular_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
VecRefListNodeAliceGenericMeshHand_append(&self->to_be_freed_of_old_staging_next_cycle, mm_node);
|
||||
}
|
||||
for (size_t i = 0; i < self->to_be_deleted.len; i++) {
|
||||
ListNodeAliceGenericMeshHand* mm_node = self->to_be_deleted.buf[i];
|
||||
AliceGenericMeshHand* mm = &mm_node->el;
|
||||
assert(mm->scheduled_for_deletion);
|
||||
assert(mm->vbo == NULL);
|
||||
assert(mm->ebo == NULL);
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->instance_attr.staging);
|
||||
MargaretBufAllocator_free(&alice->dev_local_buffers, mm->instance_attr.device_local);
|
||||
if (mm->staging_vbo.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo);
|
||||
if (mm->staging_ebo.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo);
|
||||
if (mm->staging_diffuse_tex_buf.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_diffuse_tex_buf);
|
||||
if (mm->staging_normal_tex_buf.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_normal_tex_buf);
|
||||
if (mm->staging_specular_tex_buf.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_specular_tex_buf);
|
||||
|
||||
MargaretBufAllocator_free(&alice->dev_local_buffers, mm->vbo);
|
||||
MargaretBufAllocator_free(&alice->dev_local_buffers, mm->ebo);
|
||||
MargaretImgAllocator_free(&alice->dev_local_images, mm->diffuse_texture.a);
|
||||
MargaretImgAllocator_free(&alice->dev_local_images, mm->normal_texture.a);
|
||||
MargaretImgAllocator_free(&alice->dev_local_images, mm->specular_texture.a);
|
||||
|
||||
// todo: the problem is, here we don't free some memory stored in AliceGenericMeshHand to store texture.
|
||||
// todo: but the truth is: I am gonna get rid of pixels_{,,} fields very soon, so AliceGenericMeshHand would
|
||||
// todo: be primitive again, without stupid crap
|
||||
ListAliceGenericMeshHand_erase_by_it(&self->hands, mm_node);
|
||||
}
|
||||
|
||||
self->to_be_freed_of_old_staging_next_cycle.len = 0;
|
||||
self->to_be_copied_to_device_next_cycle.len = 0;
|
||||
self->to_be_deleted.len = 0;
|
||||
}
|
||||
|
||||
void AliceAllMeshesShiny__resolve_on_another_frame(Alice* alice, AliceAllMeshesShiny* self){
|
||||
void AliceAllMeshesShiny__resolve_mesh_creation(Alice* alice, AliceAllMeshesShiny* self){
|
||||
for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) {
|
||||
AliceShinyMeshHand* mm = &self->to_be_freed_of_old_staging_next_cycle.buf[i]->el;
|
||||
assert(mm->staging_vbo.len != 0);
|
||||
assert(mm->staging_ebo.len != 0);
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo);
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo);
|
||||
mm->staging_vbo.len = 0;
|
||||
mm->staging_ebo.len = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) {
|
||||
ListNodeAliceShinyMeshHand* mm_node = self->to_be_copied_to_device_next_cycle.buf[i];
|
||||
AliceShinyMeshHand* mm = &mm_node->el;
|
||||
assert(mm->staging_vbo.len != 0);
|
||||
assert(mm->staging_ebo.len != 0);
|
||||
if (mm->scheduled_for_deletion)
|
||||
continue;
|
||||
margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_vbo, &mm->vbo);
|
||||
margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_ebo, &mm->ebo);
|
||||
VecRefListNodeAliceShinyMeshHand_append(&self->to_be_freed_of_old_staging_next_cycle, mm_node);
|
||||
}
|
||||
for (size_t i = 0; i < self->to_be_deleted.len; i++) {
|
||||
ListNodeAliceShinyMeshHand* mm_node = self->to_be_deleted.buf[i];
|
||||
AliceShinyMeshHand* mm = &mm_node->el;
|
||||
assert(mm->scheduled_for_deletion);
|
||||
assert(mm->vbo == NULL);
|
||||
assert(mm->ebo == NULL);
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->instance_attr.staging);
|
||||
MargaretBufAllocator_free(&alice->dev_local_buffers, mm->instance_attr.device_local);
|
||||
if (mm->staging_vbo.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo);
|
||||
if (mm->staging_ebo.len != 0)
|
||||
MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo);
|
||||
|
||||
MargaretBufAllocator_free(&alice->dev_local_buffers, mm->vbo);
|
||||
MargaretBufAllocator_free(&alice->dev_local_buffers, mm->ebo);
|
||||
|
||||
ListAliceShinyMeshHand_erase_by_it(&self->hands, mm_node);
|
||||
}
|
||||
|
||||
self->to_be_freed_of_old_staging_next_cycle.len = 0;
|
||||
self->to_be_copied_to_device_next_cycle.len = 0;
|
||||
self->to_be_deleted.len = 0;
|
||||
}
|
||||
|
||||
@ -1117,8 +1206,8 @@ void AliceAllMeshesShiny__resolve_on_another_frame(Alice* alice, AliceAllMeshesS
|
||||
* 3) As mentioned before, Pipeline0UBO also gets copied
|
||||
*/
|
||||
void AliceScene__another_frame(Alice* alice) {
|
||||
AliceAllMeshesGeneric__resolve_on_another_frame(alice, &alice->generic_models);
|
||||
AliceAllMeshesShiny__resolve_on_another_frame(alice, &alice->shiny_models);
|
||||
AliceAllMeshesGeneric__resolve_mesh_creation(alice, &alice->generic_models);
|
||||
AliceAllMeshesShiny__resolve_mesh_creation(alice, &alice->shiny_models);
|
||||
|
||||
for (ListNodeAliceGenericMeshHand* mm_node = alice->generic_models.hands.first; mm_node; mm_node = mm_node->next) {
|
||||
AliceGenericMeshHand* mm = &mm_node->el;
|
||||
@ -1202,9 +1291,9 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) {
|
||||
AliceGenericMeshHand* model = &mm_node->el;
|
||||
VkDescriptorSet model_indiv_descriptor_set_0 = model->mem_dependant_vk_obj.p_0a_set_0;
|
||||
|
||||
const MargaretSubbuf* dev_local_vbo = &model->vbo->device_buf;
|
||||
const MargaretSubbuf* dev_local_vbo = &model->vbo;
|
||||
const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local;
|
||||
const MargaretSubbuf* dev_local_ebo = &model->ebo->device_buf;
|
||||
const MargaretSubbuf* dev_local_ebo = &model->ebo;
|
||||
// const
|
||||
vkCmdBindVertexBuffers(alice->rendering_command_buf_0, 0,
|
||||
2, (VkBuffer[]){
|
||||
@ -1230,9 +1319,9 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) {
|
||||
1, &alice->descriptor_set_for_pipeline_0b, 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;
|
||||
const MargaretSubbuf* dev_local_vbo = &model->vbo;
|
||||
const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local;
|
||||
const MargaretSubbuf* dev_local_ebo = &model->ebo->device_buf;
|
||||
const MargaretSubbuf* dev_local_ebo = &model->ebo;
|
||||
vkCmdBindVertexBuffers(alice->rendering_command_buf_0, 0, 2, (VkBuffer[]){
|
||||
MargaretSubbuf_get_buffer(dev_local_vbo), MargaretSubbuf_get_buffer(dev_local_inst_attr)
|
||||
}, (VkDeviceSize[]){ dev_local_vbo->start, dev_local_inst_attr->start });
|
||||
@ -1394,13 +1483,6 @@ void alice_frame_drawing(Alice* alice) {
|
||||
alice->callbacks.on_another_frame(alice->guest, (float)(alice->wl.cur_frame_time - alice->wl.last_frame_time) / 1000);
|
||||
|
||||
margaret_reset_and_begin_command_buffer(alice->transfer_command_buf);
|
||||
|
||||
/* Literally everything, including lucy cache, depends on these two steps */
|
||||
AliceAllSingleUploadBuffers__resolve_on_another_frame(&alice->single_upload_buffers,
|
||||
&alice->staging_buffers, &alice->dev_local_buffers, alice->transfer_command_buf);
|
||||
AliceAllSingleUploadTextures__resolve_on_another_frame(&alice->single_upload_textures,
|
||||
&alice->staging_buffers, &alice->dev_local_images, alice->transfer_command_buf);
|
||||
|
||||
AliceScene__another_frame(alice);
|
||||
LucyGlyphCache_another_frame(&alice->lucy_cache);
|
||||
LucyRenderer_another_frame(&alice->lucy_renderer);
|
||||
@ -1879,8 +1961,8 @@ Alice* Alice_new(){
|
||||
// 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 ,
|
||||
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);
|
||||
|
||||
alice->dev_local_images = MargaretImgAllocator_new(alice->device, alice->physical_device,
|
||||
@ -1892,9 +1974,6 @@ Alice* Alice_new(){
|
||||
alice->device, alice->queue_fam, swapchain_details_res.ok,
|
||||
alice->surface, alice->render_pass_1, NULL);
|
||||
|
||||
alice->single_upload_buffers = AliceAllSingleUploadBuffers_new();
|
||||
alice->single_upload_textures = AliceAllSingleUploadTextures_new();
|
||||
|
||||
alice->generic_models = AliceAllMeshesGeneric_new();
|
||||
alice->shiny_models = AliceAllMeshesShiny_new();
|
||||
alice->pipeline0_ubo.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO));
|
||||
@ -1921,7 +2000,7 @@ Alice* Alice_new(){
|
||||
if (ft_init_err)
|
||||
abortf("Can't init free type library\n");
|
||||
|
||||
alice->lucy_cache = LucyGlyphCache_new(engine_reference, &alice->single_upload_textures);
|
||||
alice->lucy_cache = LucyGlyphCache_new(engine_reference);
|
||||
|
||||
alice->lucy_renderer = LucyRenderer_new(engine_reference, &alice->lucy_cache, root_dir, alice->render_pass_1, 0);
|
||||
|
||||
|
||||
@ -1,209 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/* I sometimes call this sub-namespace of Alice namespace Abigail. Though I hadn't renamed it to Abigail yet.
|
||||
* Abigail does not depend on Alice Engine. It only depends on margaret. So systems like Lucy can use it
|
||||
* without creating any sus circular dependepncies.
|
||||
*/
|
||||
|
||||
#include "../margaret/vulkan_utils.h"
|
||||
|
||||
/* Handler of a read-only buffer that can be uploaded and deleted at any time with it's staging buffer automatically
|
||||
* deleted (Similar to what AliceTextureUploadedOnce does to textures) */
|
||||
typedef struct {
|
||||
MargaretSubbuf staging;
|
||||
MargaretSubbuf device_buf;
|
||||
bool scheduled_for_deletion;
|
||||
} AliceBufferUplOnce;
|
||||
|
||||
typedef AliceBufferUplOnce* RefAliceBufferUplOnce;
|
||||
|
||||
#include "../../../gen/l1/eve/alice/VecRefAliceBufferUplOnce.h"
|
||||
|
||||
/* Handler of a texture that can be uploaded and deleted at any time with it's staging buffer automatically deleted.
|
||||
* Stores VkImageView as a bonus */
|
||||
typedef struct {
|
||||
MargaretSubbuf staging;
|
||||
MargaretImg img;
|
||||
VkImageView view;
|
||||
bool scheduled_for_deletion;
|
||||
} AliceTextureUplOnce;
|
||||
|
||||
typedef AliceTextureUplOnce* RefAliceTextureUplOnce;
|
||||
|
||||
#include "../../../gen/l1/eve/alice/VecRefAliceTextureUplOnce.h"
|
||||
|
||||
typedef struct {
|
||||
VecRefAliceBufferUplOnce to_be_freed_of_old_staging_next_cycle;
|
||||
VecRefAliceBufferUplOnce to_be_copied_to_device_next_cycle;
|
||||
VecRefAliceBufferUplOnce to_be_deleted;
|
||||
} AliceAllSingleUploadBuffers;
|
||||
|
||||
AliceAllSingleUploadBuffers AliceAllSingleUploadBuffers_new() {
|
||||
return (AliceAllSingleUploadBuffers){
|
||||
.to_be_freed_of_old_staging_next_cycle = VecRefAliceBufferUplOnce_new(),
|
||||
.to_be_copied_to_device_next_cycle = VecRefAliceBufferUplOnce_new(),
|
||||
.to_be_deleted = VecRefAliceBufferUplOnce_new(),
|
||||
};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
VecRefAliceTextureUplOnce to_be_freed_of_old_staging_next_cycle;
|
||||
VecRefAliceTextureUplOnce to_be_copied_to_device_next_cycle;
|
||||
VecRefAliceTextureUplOnce to_be_deleted;
|
||||
} AliceAllSingleUploadTextures;
|
||||
|
||||
AliceAllSingleUploadTextures AliceAllSingleUploadTextures_new(){
|
||||
return (AliceAllSingleUploadTextures){
|
||||
.to_be_freed_of_old_staging_next_cycle = VecRefAliceTextureUplOnce_new(),
|
||||
.to_be_copied_to_device_next_cycle = VecRefAliceTextureUplOnce_new(),
|
||||
.to_be_deleted = VecRefAliceTextureUplOnce_new(),
|
||||
};
|
||||
}
|
||||
|
||||
void AliceAllSingleUploadBuffers__resolve_on_another_frame(AliceAllSingleUploadBuffers* self,
|
||||
MargaretBufAllocator* staging_buffers, MargaretBufAllocator* dev_local_buffers, VkCommandBuffer transfer_cmd_buffer
|
||||
) {
|
||||
for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) {
|
||||
AliceBufferUplOnce* mm = self->to_be_freed_of_old_staging_next_cycle.buf[i];
|
||||
assert(mm->staging.len != 0);
|
||||
MargaretBufAllocator_free(staging_buffers, mm->staging);
|
||||
mm->staging.len = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) {
|
||||
AliceBufferUplOnce* mm = self->to_be_copied_to_device_next_cycle.buf[i];
|
||||
assert(mm->staging.len != 0);
|
||||
if (mm->scheduled_for_deletion)
|
||||
continue;
|
||||
margaret_rec_cmd_copy_buffer_one_to_one(transfer_cmd_buffer, &mm->staging, &mm->device_buf);
|
||||
VecRefAliceBufferUplOnce_append(&self->to_be_freed_of_old_staging_next_cycle, mm);
|
||||
}
|
||||
for (size_t i = 0; i < self->to_be_deleted.len; i++) {
|
||||
AliceBufferUplOnce* mm = self->to_be_deleted.buf[i];
|
||||
assert(mm->scheduled_for_deletion);
|
||||
if (mm->staging.len != 0)
|
||||
MargaretBufAllocator_free(staging_buffers, mm->staging);
|
||||
MargaretBufAllocator_free(dev_local_buffers, mm->device_buf);
|
||||
free(mm);
|
||||
}
|
||||
|
||||
self->to_be_freed_of_old_staging_next_cycle.len = 0;
|
||||
self->to_be_copied_to_device_next_cycle.len = 0;
|
||||
self->to_be_deleted.len = 0;
|
||||
}
|
||||
|
||||
void AliceAllSingleUploadTextures__resolve_on_another_frame(AliceAllSingleUploadTextures* self,
|
||||
MargaretBufAllocator* staging_buffers, MargaretImgAllocator* dev_local_images, VkCommandBuffer transfer_cmd_buffer
|
||||
) {
|
||||
for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) {
|
||||
AliceTextureUplOnce* mm = self->to_be_freed_of_old_staging_next_cycle.buf[i];
|
||||
assert(mm->staging.len != 0);
|
||||
MargaretBufAllocator_free(staging_buffers, mm->staging);
|
||||
mm->staging.len = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) {
|
||||
AliceTextureUplOnce* mm = self->to_be_copied_to_device_next_cycle.buf[i];
|
||||
assert(mm->staging.len != 0);
|
||||
if (mm->scheduled_for_deletion)
|
||||
continue;
|
||||
margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(transfer_cmd_buffer,
|
||||
&mm->staging, &mm->img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
VecRefAliceTextureUplOnce_append(&self->to_be_freed_of_old_staging_next_cycle, mm);
|
||||
}
|
||||
for (size_t i = 0; i < self->to_be_deleted.len; i++) {
|
||||
AliceTextureUplOnce* mm = self->to_be_deleted.buf[i];
|
||||
assert(mm->scheduled_for_deletion);
|
||||
if (mm->staging.len != 0)
|
||||
MargaretBufAllocator_free(staging_buffers, mm->staging);
|
||||
|
||||
MargaretImgAllocator_free(dev_local_images, mm->img.a);
|
||||
vkDestroyImageView(dev_local_images->device, mm->view, NULL);
|
||||
free(mm);
|
||||
}
|
||||
|
||||
self->to_be_freed_of_old_staging_next_cycle.len = 0;
|
||||
self->to_be_copied_to_device_next_cycle.len = 0;
|
||||
self->to_be_deleted.len = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Doesn't get automatically added to `to_be_copied_to_device_next_cycle` */
|
||||
AliceBufferUplOnce* AliceBufferUplOnce_new(size_t len,
|
||||
MargaretBufAllocator* staging_buffers, MargaretBufAllocator* dev_local_buffers
|
||||
) {
|
||||
AliceBufferUplOnce* res = (AliceBufferUplOnce*)safe_malloc(sizeof(AliceBufferUplOnce));
|
||||
res->staging = MargaretBufAllocator_alloc(staging_buffers, len);
|
||||
res->device_buf = MargaretBufAllocator_alloc(dev_local_buffers, len);
|
||||
res->scheduled_for_deletion = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
void* AliceBufferUplOnce_get_mapped_staging(AliceBufferUplOnce* self) {
|
||||
return MargaretSubbuf_get_mapped(&self->staging);
|
||||
}
|
||||
|
||||
void AliceAllSingleUploadBuffers_register(AliceAllSingleUploadBuffers* self, AliceBufferUplOnce* obj) {
|
||||
assert(obj->staging.len > 0);
|
||||
assert(!obj->scheduled_for_deletion);
|
||||
VecRefAliceBufferUplOnce_append(&self->to_be_copied_to_device_next_cycle, obj);
|
||||
}
|
||||
|
||||
AliceBufferUplOnce* AliceAllSingleUploadBuffers_register_new(AliceAllSingleUploadBuffers* self, size_t len,
|
||||
MargaretBufAllocator* staging_buffers, MargaretBufAllocator* dev_local_buffers
|
||||
) {
|
||||
AliceBufferUplOnce* res = AliceBufferUplOnce_new(len, staging_buffers, dev_local_buffers);
|
||||
AliceAllSingleUploadBuffers_register(self, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void AliceAllSingleUploadBuffers_delete(AliceAllSingleUploadBuffers* self, AliceBufferUplOnce* obj) {
|
||||
assert(obj);
|
||||
obj->scheduled_for_deletion = true;
|
||||
VecRefAliceBufferUplOnce_append(&self->to_be_deleted, obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Doesn't get automatically added to `to_be_copied_to_device_next_cycle`
|
||||
* Only works for VK_IMAGE_ASPECT_COLOR_BIT images */
|
||||
AliceTextureUplOnce* AliceTextureUplOnce_new(U64 width, U64 height, U64 pixel_sz, VkFormat format,
|
||||
VkImageUsageFlags usage, MargaretBufAllocator* staging_buffers, MargaretImgAllocator* dev_local_images
|
||||
) {
|
||||
assert(pixel_sz == margaret_singleplane_format_to_sizeof_type(format));
|
||||
AliceTextureUplOnce* res = (AliceTextureUplOnce*)safe_malloc(sizeof(AliceTextureUplOnce));
|
||||
res->staging = MargaretBufAllocator_alloc(staging_buffers, width * height * pixel_sz);
|
||||
res->img = MargaretImgAllocator_alloc(dev_local_images, width, height, format, usage);
|
||||
res->view = margaret_create_view_for_image(dev_local_images->device, res->img.a.image,
|
||||
format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
res->scheduled_for_deletion = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
void* AliceTextureUplOnce_get_mapped_staging(AliceTextureUplOnce* self) {
|
||||
return MargaretSubbuf_get_mapped(&self->staging);
|
||||
}
|
||||
|
||||
void AliceAllSingleUploadTextures_register(AliceAllSingleUploadTextures* self, AliceTextureUplOnce* obj) {
|
||||
assert(obj->staging.len > 0);
|
||||
assert(!obj->scheduled_for_deletion);
|
||||
VecRefAliceTextureUplOnce_append(&self->to_be_copied_to_device_next_cycle, obj);
|
||||
}
|
||||
|
||||
AliceTextureUplOnce* AliceAllSingleUploadTextures_register_new(AliceAllSingleUploadTextures* self,
|
||||
U64 width, U64 height, U64 pixel_sz, VkFormat format,
|
||||
VkImageUsageFlags usage, MargaretBufAllocator* staging_buffers, MargaretImgAllocator* dev_local_images
|
||||
) {
|
||||
AliceTextureUplOnce* res = AliceTextureUplOnce_new(width, height, pixel_sz, format, usage,
|
||||
staging_buffers, dev_local_images);
|
||||
AliceAllSingleUploadTextures_register(self, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void AliceAllSingleUploadTextures_delete(AliceAllSingleUploadTextures* self, AliceTextureUplOnce* obj) {
|
||||
assert(obj);
|
||||
obj->scheduled_for_deletion = true;
|
||||
VecRefAliceTextureUplOnce_append(&self->to_be_deleted, obj);
|
||||
}
|
||||
@ -1,23 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "../margaret/vulkan_utils.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "../../../gen/l1/VecAndSpan_U32Segment.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkDescriptorImageInfo.h"
|
||||
#include "../../../gen/l1/pixel_masses.h"
|
||||
#include "../../../gen/l1/VecAndSpan_U32.h"
|
||||
|
||||
#include "../../l1_5/core/buff_rb_tree_node.h"
|
||||
#include "../../l1_5/core/rb_tree_node.h"
|
||||
#include "../alice/transfer_in_mainloop.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#define LUCY_MAX_DESCRIPTOR_COUNT 100
|
||||
|
||||
typedef U32 lucy_image_index_t;
|
||||
|
||||
typedef struct {
|
||||
AliceTextureUplOnce* tex;
|
||||
/* This value is actually Option<MargaretSubbuf>. If staging_buffer is already deleted (after it is no longer used),
|
||||
* staging_buffer.len will be 0 */
|
||||
MargaretSubbuf staging_buffer;
|
||||
MargaretImg img;
|
||||
VkImageView img_view;
|
||||
U64 usage;
|
||||
/* Is this image scheduled for deletion on th next cycle. */
|
||||
bool scheduled_for_deletion;
|
||||
/* 0 if this image isn't scheduled for deletion on th next cycle.
|
||||
* 1 if it is */
|
||||
int scheduled_for_deletion;
|
||||
} LucyImage;
|
||||
|
||||
#include "../../../gen/l1/eve/lucy/OptionLucyImage.h"
|
||||
@ -64,19 +71,19 @@ struct LucyFace {
|
||||
|
||||
struct LucyGlyphCache {
|
||||
MargaretEngineReference ve;
|
||||
AliceAllSingleUploadTextures* single_upload_textures;
|
||||
|
||||
VecOptionLucyImage image_slots;
|
||||
VkDescriptorSetLayout descriptor_set_layout;
|
||||
VkDescriptorSet descriptor_set;
|
||||
|
||||
/* We can delete images and link images to descriptor set only when frame isn't in flight */
|
||||
VecU32 to_be_written_to_descriptor_set;
|
||||
/* to_be_freed_of_old_staging_next_cycle never intersect with to_be_copied_to_device_next_cycle */
|
||||
VecU32 to_be_freed_of_old_staging_next_cycle;
|
||||
VecU32 to_be_copied_to_device_next_cycle;
|
||||
/* deletion will be performed last */
|
||||
VecU32 to_be_deleted;
|
||||
};
|
||||
|
||||
|
||||
LucyGlyphCache LucyGlyphCache_new(MargaretEngineReference ve, AliceAllSingleUploadTextures* single_upload_textures){
|
||||
LucyGlyphCache LucyGlyphCache_new(MargaretEngineReference ve){
|
||||
VkDescriptorSetLayout my_desc_set_layout;
|
||||
VkDescriptorSetLayoutBindingFlagsCreateInfo set_layout_crinfo_flags = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
@ -101,9 +108,10 @@ LucyGlyphCache LucyGlyphCache_new(MargaretEngineReference ve, AliceAllSingleUplo
|
||||
image_slots.buf[i].variant = Option_None;
|
||||
}
|
||||
return (LucyGlyphCache){
|
||||
.ve = ve, .single_upload_textures = single_upload_textures, .image_slots = image_slots,
|
||||
.ve = ve, .image_slots = image_slots,
|
||||
.descriptor_set_layout = my_desc_set_layout, .descriptor_set = descriptor_set,
|
||||
.to_be_written_to_descriptor_set = VecU32_new(),
|
||||
.to_be_freed_of_old_staging_next_cycle = VecU32_new(),
|
||||
.to_be_copied_to_device_next_cycle = VecU32_new(),
|
||||
.to_be_deleted = VecU32_new()};
|
||||
}
|
||||
|
||||
@ -118,9 +126,7 @@ void LucyFaceFixedSize_get_rid_of_myself(LucyFaceFixedSize* self){
|
||||
assert(img->usage > 0);
|
||||
if (--img->usage) {
|
||||
assert(!img->scheduled_for_deletion);
|
||||
img->scheduled_for_deletion = true;
|
||||
AliceAllSingleUploadTextures_delete(cache->single_upload_textures, img->tex);
|
||||
img->tex = NULL;
|
||||
img->scheduled_for_deletion = 1;
|
||||
VecU32_append(&cache->to_be_deleted, slot_id);
|
||||
}
|
||||
}
|
||||
@ -186,12 +192,12 @@ void LucyGlyphCache_add_glyphs__close_img(
|
||||
assert(!img->scheduled_for_deletion);
|
||||
img_width = MAX_U32(img_width, 10); // Just a precaution. empty buffers aren't supported by Margaret
|
||||
img_height = MAX_U32(img_height, 10);
|
||||
|
||||
img->tex = AliceAllSingleUploadTextures_register_new(cache->single_upload_textures,
|
||||
img_width, img_height, sizeof(U8), VK_FORMAT_R8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
cache->ve.staging_buffers, cache->ve.dev_local_images);
|
||||
VecU32_append(&cache->to_be_written_to_descriptor_set, img_slot_id);
|
||||
VecU32_append(&cache->to_be_copied_to_device_next_cycle, img_slot_id);
|
||||
img->staging_buffer = MargaretBufAllocator_alloc(cache->ve.staging_buffers, img_width * img_height * 1);
|
||||
img->img = MargaretImgAllocator_alloc(cache->ve.dev_local_images, img_width, img_height, VK_FORMAT_R8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
|
||||
img->img_view = margaret_create_view_for_image(cache->ve.device, img->img.a.image,
|
||||
VK_FORMAT_R8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
|
||||
void LucyGlyphCache_add_glyphs(VecLucyGlyphCachingRequest requests_for_faces){
|
||||
@ -263,6 +269,7 @@ void LucyGlyphCache_add_glyphs(VecLucyGlyphCachingRequest requests_for_faces){
|
||||
LucyPositionedStagingGlyph* p_glyph;
|
||||
one_more_chance:
|
||||
{}
|
||||
int s = 23123;
|
||||
p_glyph = &ready.buf[j];
|
||||
LucyImage* img = &VecOptionLucyImage_mat(&cache->image_slots, img_slot_id)->some;
|
||||
U64 new_width_required = p_glyph->bitmap.width + starting_x;
|
||||
@ -312,8 +319,8 @@ void LucyGlyphCache_add_glyphs(VecLucyGlyphCachingRequest requests_for_faces){
|
||||
for (size_t j = 0; j < ready.len; j++) {
|
||||
LucyPositionedStagingGlyph* p_glyph = &ready.buf[j];
|
||||
LucyImage* image = &VecOptionLucyImage_mat(&cache->image_slots, p_glyph->img_slot_id)->some;
|
||||
U64 staging_width = image->tex->img.width;
|
||||
U8* staging = (U8*)AliceTextureUplOnce_get_mapped_staging(image->tex);
|
||||
U64 staging_width = image->img.width;
|
||||
U8* staging = (U8*)MargaretSubbuf_get_mapped(&image->staging_buffer);
|
||||
for (U64 y = 0; y < p_glyph->bitmap.height; y++) {
|
||||
U64 Y = y + p_glyph->pos.y;
|
||||
for (U64 x = 0; x < p_glyph->bitmap.width; x++) {
|
||||
@ -332,18 +339,31 @@ void LucyGlyphCache_drop(LucyGlyphCache self){
|
||||
for (size_t i = 0; i < self.image_slots.len; i++) {
|
||||
assert(self.image_slots.buf[i].variant == Option_None);
|
||||
}
|
||||
VecU32_drop(self.to_be_written_to_descriptor_set);
|
||||
VecU32_drop(self.to_be_freed_of_old_staging_next_cycle);
|
||||
VecU32_drop(self.to_be_copied_to_device_next_cycle);
|
||||
VecU32_drop(self.to_be_deleted);
|
||||
}
|
||||
|
||||
void LucyGlyphCache_another_frame(LucyGlyphCache* self){
|
||||
for (size_t i = 0; i < self->to_be_written_to_descriptor_set.len; i++) {
|
||||
U32 slot_id = self->to_be_written_to_descriptor_set.buf[i];
|
||||
for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) {
|
||||
U32 slot_id = self->to_be_freed_of_old_staging_next_cycle.buf[i];
|
||||
LucyImage* img = &self->image_slots.buf[slot_id].some;
|
||||
assert(img->staging_buffer.len != 0);
|
||||
MargaretBufAllocator_free(self->ve.staging_buffers, img->staging_buffer);
|
||||
img->staging_buffer.len = 0;
|
||||
}
|
||||
for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) {
|
||||
U32 slot_id = self->to_be_copied_to_device_next_cycle.buf[i];
|
||||
OptionLucyImage* img_slot = &self->image_slots.buf[slot_id];
|
||||
assert(img_slot->variant == Option_Some);
|
||||
LucyImage* img = &img_slot->some;
|
||||
assert(img->staging_buffer.len != 0);
|
||||
if (img->scheduled_for_deletion)
|
||||
continue;
|
||||
margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(self->ve.transfer_cmd_buffer,
|
||||
&img->staging_buffer, &img->img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
VecU32_append(&self->to_be_freed_of_old_staging_next_cycle, slot_id);
|
||||
|
||||
vkUpdateDescriptorSets(self->ve.device, 1, &(VkWriteDescriptorSet){
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
@ -351,7 +371,7 @@ void LucyGlyphCache_another_frame(LucyGlyphCache* self){
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &(VkDescriptorImageInfo){
|
||||
.sampler = self->ve.nearest_sampler, .imageView = img->tex->view,
|
||||
.sampler = self->ve.nearest_sampler, .imageView = img->img_view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
}
|
||||
}, 0, NULL);
|
||||
@ -359,16 +379,19 @@ void LucyGlyphCache_another_frame(LucyGlyphCache* self){
|
||||
/* We technically could carry out each deletion request in O(1) and each img creation request in O(1),
|
||||
* but who cares, it's no problem going over the entire descriptor set when something get's added or deleted */
|
||||
for (size_t i = 0; i < self->to_be_deleted.len; i++) {
|
||||
U32 slot_id = self->to_be_deleted.buf[i];
|
||||
U32 slot_id = self->to_be_copied_to_device_next_cycle.buf[i];
|
||||
OptionLucyImage* img_slot = &self->image_slots.buf[slot_id];
|
||||
assert(img_slot->variant == Option_Some);
|
||||
LucyImage* img = &img_slot->some;
|
||||
assert(img->scheduled_for_deletion);
|
||||
assert(img->usage == 0);
|
||||
assert(img->tex == NULL);
|
||||
if (img->staging_buffer.len != 0)
|
||||
MargaretBufAllocator_free(self->ve.staging_buffers, img->staging_buffer);
|
||||
MargaretImgAllocator_free(self->ve.dev_local_images, img->img.a);
|
||||
img_slot->variant = Option_None;
|
||||
}
|
||||
self->to_be_written_to_descriptor_set.len = 0;
|
||||
self->to_be_freed_of_old_staging_next_cycle.len = 0;
|
||||
self->to_be_copied_to_device_next_cycle.len = 0;
|
||||
self->to_be_deleted.len = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -97,8 +97,8 @@ void LucyRenderer_draw_char_glyph(LucyRenderer* self, vec4 color, ivec2 pos, Luc
|
||||
OptionLucyImage* img_slot = VecOptionLucyImage_mat(&self->cache->image_slots, glyph->img_slot_id);
|
||||
assert(img_slot->variant == Option_Some);
|
||||
LucyImage* img = &img_slot->some;
|
||||
float atlas_w = (float)img->tex->img.width;
|
||||
float atlas_h = (float)img->tex->img.height;
|
||||
float atlas_w = (float)img->img.width;
|
||||
float atlas_h = (float)img->img.height;
|
||||
ivec2 positioned = ivec2_add_ivec2(pos, glyph->bearing);
|
||||
|
||||
U64 needed_vbo_length = (self->glyphs_count + 1) * sizeof(LucyRenderInstance);
|
||||
|
||||
@ -1120,7 +1120,7 @@ VkPipeline margaret_create_triangle_pipeline_one_attachment(
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
|
||||
@ -1246,35 +1246,3 @@ void margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(
|
||||
});
|
||||
dst->current_layout = dst_new_layout;
|
||||
}
|
||||
|
||||
U64 margaret_singleplane_format_to_sizeof_type(VkFormat type){
|
||||
switch (type) {
|
||||
case VK_FORMAT_R32G32B32A32_SFLOAT: return 16;
|
||||
case VK_FORMAT_R32G32B32_SFLOAT: return 12;
|
||||
case VK_FORMAT_R32G32_SFLOAT: return 8;
|
||||
case VK_FORMAT_R32_SFLOAT: return 4;
|
||||
case VK_FORMAT_R16_SFLOAT: return 2;
|
||||
case VK_FORMAT_R16G16_SFLOAT: return 4;
|
||||
case VK_FORMAT_R16G16B16_SFLOAT: return 6;
|
||||
case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
|
||||
|
||||
case VK_FORMAT_R16_UNORM: return 2;
|
||||
case VK_FORMAT_R16G16_UNORM: return 4;
|
||||
case VK_FORMAT_R16G16B16_UNORM: return 6;
|
||||
case VK_FORMAT_R16G16B16A16_UNORM: return 8;
|
||||
case VK_FORMAT_R8G8B8A8_UNORM: return 4;
|
||||
case VK_FORMAT_R8G8B8_UNORM: return 3;
|
||||
case VK_FORMAT_R8G8_UNORM: return 2;
|
||||
case VK_FORMAT_R8_UNORM: return 1;
|
||||
|
||||
|
||||
case VK_FORMAT_R32_UINT: return 4;
|
||||
case VK_FORMAT_R32G32_UINT: return 8;
|
||||
case VK_FORMAT_R32G32B32_UINT: return 12;
|
||||
case VK_FORMAT_R32G32B32A32_UINT: return 16;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_SRGB: return 4;
|
||||
default:
|
||||
abortf("Jokes on you\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,8 +96,6 @@ typedef struct{
|
||||
U64 misses_count;
|
||||
U64 hits_count;
|
||||
Vecvec3 bullets_stuck_on_ROA;
|
||||
|
||||
MargaretSubbuf sb;
|
||||
} R4BetaState;
|
||||
|
||||
/* We are surrounded by a giant cubic mesh of light sources */
|
||||
|
||||
@ -13,4 +13,5 @@ layout (binding=0) uniform sampler2D images[];
|
||||
void main(){
|
||||
float I = texture(images[nonuniformEXT(tex_ind)], tex_cord).r;
|
||||
fin_color = vec4(color.rgb, color.a * I);
|
||||
//fin_color = vec4(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
@ -38,5 +38,4 @@ void main(){
|
||||
vsout_tex_ind = tex_ind;
|
||||
vec2 pos = all_v_pos[gl_VertexIndex % 6];
|
||||
gl_Position = vec4(deng(width, pos.x), deng(height, pos.y), 0, 1);
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user