diff options
Diffstat (limited to 'src/atlas.cc')
| -rw-r--r-- | src/atlas.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/atlas.cc b/src/atlas.cc new file mode 100644 index 0000000..4b756eb --- /dev/null +++ b/src/atlas.cc @@ -0,0 +1,92 @@ +#include "atlas.h" + +#include "mimalloc.h" +#include "utils.h" + +static void wayc_atlas_gpu_usage_desc(struct sg_image_usage* usage) { + wayc_notnull(usage); + + usage->immutable = false; + usage->dynamic_update = true; +} + +static void wayc_atlas_gpu_desc(struct sg_image_desc* desc, u32 width, + u32 height, enum sg_pixel_format format) { + wayc_notnull(desc); + + struct sg_image_usage usage = {}; + wayc_atlas_gpu_usage_desc(&usage); + + desc->type = SG_IMAGETYPE_2D; + desc->width = width; + desc->height = height; + desc->num_mipmaps = 1; + desc->pixel_format = format; + desc->usage = usage; +} + +static inline usize wayc_atlas_size(struct atlas_s* atlas) { + wayc_notnull(atlas); + return atlas->width * atlas->height; +} + +enum atlas_error_e wayc_atlas_init(struct atlas_s* atlas, u32 width, u32 height, + enum sg_pixel_format format) { + wayc_notnull(atlas); + + bool success = false; + + usize atlas_size = wayc_atlas_size(atlas); + u8* cpu_atlas = (u8*)mi_malloc(atlas_size); + wayc_defer_cond(mi_free(cpu_atlas);, success, true); + + struct sg_image_desc desc = {}; + wayc_atlas_gpu_desc(&desc, width, height, format); + + struct sg_image gpu_atlas = sg_make_image(&desc); + if (sg_query_image_state(gpu_atlas) != SG_RESOURCESTATE_VALID) + return ATLAS_ERROR_GPU_ATLAS; + + atlas->width = width; + atlas->height = height; + atlas->cpu_atlas = cpu_atlas; + atlas->gpu_atlas = gpu_atlas; + atlas->cpu_dirty = false; + + success = true; + return ATLAS_ERROR_NONE; +} + +enum atlas_error_e wayc_atlas_flush(struct atlas_s* atlas) { + wayc_notnull(atlas); + if (!atlas->cpu_dirty) return ATLAS_ERROR_NONE; + + struct sg_range range = {}; + range.ptr = atlas->cpu_atlas; + range.size = wayc_atlas_size(atlas); + + struct sg_image_data data = {}; + data.mip_levels[0] = range; + + sg_update_image(atlas->gpu_atlas, &data); + if (sg_query_image_state(atlas->gpu_atlas) != SG_RESOURCESTATE_VALID) + return ATLAS_ERROR_UPLOAD_FAILED; + + atlas->cpu_dirty = false; + return ATLAS_ERROR_NONE; +} + +void wayc_atlas_deinit(struct atlas_s* atlas) { + wayc_notnull(atlas); + + enum sg_resource_state state = sg_query_image_state(atlas->gpu_atlas); + if (atlas->cpu_atlas == nullptr || state != SG_RESOURCESTATE_VALID) return; + + sg_destroy_image(atlas->gpu_atlas); + mi_free(atlas->cpu_atlas); + + atlas->width = 0; + atlas->height = 0; + atlas->cpu_atlas = nullptr; + atlas->gpu_atlas = {}; +} |
