|
|
@ -8,6 +8,7 @@
|
|
|
|
#include "string.h"
|
|
|
|
#include "string.h"
|
|
|
|
#include "vk_mem_alloc.h"
|
|
|
|
#include "vk_mem_alloc.h"
|
|
|
|
#include "vulkan/vulkan_core.h"
|
|
|
|
#include "vulkan/vulkan_core.h"
|
|
|
|
|
|
|
|
#include "spng.h"
|
|
|
|
|
|
|
|
|
|
|
|
VkShaderModule load_shader_file(const char* path, VkDevice device) {
|
|
|
|
VkShaderModule load_shader_file(const char* path, VkDevice device) {
|
|
|
|
FILE* file;
|
|
|
|
FILE* file;
|
|
|
@ -366,6 +367,134 @@ VkResult create_layer(
|
|
|
|
return VK_SUCCESS;
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkResult load_texture(
|
|
|
|
|
|
|
|
VkDevice device,
|
|
|
|
|
|
|
|
VmaAllocator allocator,
|
|
|
|
|
|
|
|
UIContextStorage* context,
|
|
|
|
|
|
|
|
uint32_t index,
|
|
|
|
|
|
|
|
VkCommandPool transfer_pool,
|
|
|
|
|
|
|
|
Queue transfer_queue,
|
|
|
|
|
|
|
|
const char* png_path,
|
|
|
|
|
|
|
|
TextureStorage* memory) {
|
|
|
|
|
|
|
|
spng_ctx* spng = spng_ctx_new(0);
|
|
|
|
|
|
|
|
if(spng == NULL) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FILE* png_file = fopen(png_path, "rb");
|
|
|
|
|
|
|
|
if(png_file == NULL) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fseek(png_file, 0, SEEK_END);
|
|
|
|
|
|
|
|
int error = fseek(png_file, 0, SEEK_END);
|
|
|
|
|
|
|
|
if(error != 0) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t png_size = ftell(png_file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
error = fseek(png_file, 0, SEEK_SET);
|
|
|
|
|
|
|
|
if(error != 0) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* png = malloc(png_size);
|
|
|
|
|
|
|
|
if(png == NULL) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t read = fread(png, png_size, 1, png_file);
|
|
|
|
|
|
|
|
if(read != png_size) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fclose(png_file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
spng_set_png_buffer(spng, png, png_size);
|
|
|
|
|
|
|
|
size_t out_size;
|
|
|
|
|
|
|
|
spng_decoded_image_size(spng, SPNG_FMT_RGBA8, &out_size);
|
|
|
|
|
|
|
|
struct spng_ihdr ihdr;
|
|
|
|
|
|
|
|
spng_get_ihdr(spng, &ihdr);
|
|
|
|
|
|
|
|
void* image_buffer = malloc(out_size);
|
|
|
|
|
|
|
|
if(image_buffer == NULL) {
|
|
|
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
spng_decode_image(spng, image_buffer, out_size, SPNG_FMT_RGBA8, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkImageCreateInfo image_info = {
|
|
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
|
|
|
|
|
|
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
|
|
|
|
|
|
|
.extent = {
|
|
|
|
|
|
|
|
.width = ihdr.width,
|
|
|
|
|
|
|
|
.height = ihdr.height,
|
|
|
|
|
|
|
|
.depth = 1,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
.mipLevels = 1,
|
|
|
|
|
|
|
|
.arrayLayers = 1,
|
|
|
|
|
|
|
|
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
|
|
|
|
|
|
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
|
|
|
|
|
|
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
|
|
|
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
|
|
|
.imageType = VK_IMAGE_TYPE_2D,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VmaAllocationCreateInfo memory_info = {
|
|
|
|
|
|
|
|
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkBuffer transfer;
|
|
|
|
|
|
|
|
VmaAllocation transfer_memory;
|
|
|
|
|
|
|
|
void* mapped;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VK_RESULT(vmaCreateImage(allocator, &image_info, &memory_info, &memory->image, &memory->image_memory, NULL));
|
|
|
|
|
|
|
|
VK_RESULT(create_transfer_buffer(allocator, sizeof(uint32_t)*ihdr.width*ihdr.height, &transfer, &transfer_memory, &mapped));
|
|
|
|
|
|
|
|
memcpy(mapped, image_buffer, sizeof(uint32_t)*ihdr.height*ihdr.width);
|
|
|
|
|
|
|
|
VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkImageMemoryBarrier first_barrier = {
|
|
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
|
|
|
.image = memory->image,
|
|
|
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
|
|
|
|
|
|
.subresourceRange = {
|
|
|
|
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
|
|
|
.levelCount = 1,
|
|
|
|
|
|
|
|
.layerCount = 1,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
.srcAccessMask = 0,
|
|
|
|
|
|
|
|
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &first_barrier);
|
|
|
|
|
|
|
|
VkBufferImageCopy image_copy = {
|
|
|
|
|
|
|
|
.imageExtent = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
vkCmdCopyBufferToImage(command_buffer, transfer, memory->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkImageMemoryBarrier second_barrier = {
|
|
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &second_barrier);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VK_RESULT(command_end_single(device, command_buffer, transfer_pool, transfer_queue));
|
|
|
|
|
|
|
|
vkQueueWaitIdle(transfer_queue.handle);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
destroy_transfer_buffer(allocator, transfer, transfer_memory);
|
|
|
|
|
|
|
|
free(image_buffer);
|
|
|
|
|
|
|
|
free(png);
|
|
|
|
|
|
|
|
spng_ctx_free(spng);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult load_font(
|
|
|
|
VkResult load_font(
|
|
|
|
VkDevice device,
|
|
|
|
VkDevice device,
|
|
|
|
VmaAllocator allocator,
|
|
|
|
VmaAllocator allocator,
|
|
|
@ -462,7 +591,6 @@ VkResult load_font(
|
|
|
|
|
|
|
|
|
|
|
|
VkImageCreateInfo image_info = {
|
|
|
|
VkImageCreateInfo image_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
|
|
|
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
|
|
|
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
|
|
|
.extent.depth = 1,
|
|
|
|
.extent.depth = 1,
|
|
|
|
.extent.width = info.width,
|
|
|
|
.extent.width = info.width,
|
|
|
@ -564,8 +692,8 @@ VkResult load_font(
|
|
|
|
|
|
|
|
|
|
|
|
VkSamplerCreateInfo sampler_info = {
|
|
|
|
VkSamplerCreateInfo sampler_info = {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
|
|
|
.magFilter = VK_FILTER_CUBIC_IMG,
|
|
|
|
.magFilter = VK_FILTER_NEAREST,
|
|
|
|
.minFilter = VK_FILTER_CUBIC_IMG,
|
|
|
|
.minFilter = VK_FILTER_NEAREST,
|
|
|
|
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
|
@ -754,8 +882,10 @@ VkResult create_ui_context(
|
|
|
|
VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped));
|
|
|
|
VK_RESULT(create_transfer_buffer(allocator, sizeof(UIContext), &transfer, &transfer_memory, (void**)&mapped));
|
|
|
|
|
|
|
|
|
|
|
|
memory->data.font_infos = buffer_address(device, memory->font_infos);
|
|
|
|
memory->data.font_infos = buffer_address(device, memory->font_infos);
|
|
|
|
memory->data.scale[0] = window_scale[0] / swapchain_extent.width;
|
|
|
|
memory->data.screen[0] = window_scale[0] / swapchain_extent.width;
|
|
|
|
memory->data.scale[1] = window_scale[1] / swapchain_extent.height;
|
|
|
|
memory->data.screen[1] = window_scale[1] / swapchain_extent.height;
|
|
|
|
|
|
|
|
memory->data.scale[0] = window_scale[0];
|
|
|
|
|
|
|
|
memory->data.scale[1] = window_scale[1];
|
|
|
|
memcpy(mapped, &memory->data, sizeof(UIContext));
|
|
|
|
memcpy(mapped, &memory->data, sizeof(UIContext));
|
|
|
|
|
|
|
|
|
|
|
|
VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
|
|
|
|
VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool);
|
|
|
@ -793,6 +923,29 @@ void set_ui_rect(
|
|
|
|
drawable->code = 0;
|
|
|
|
drawable->code = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void set_ui_image(
|
|
|
|
|
|
|
|
float x,
|
|
|
|
|
|
|
|
float y,
|
|
|
|
|
|
|
|
float width,
|
|
|
|
|
|
|
|
float height,
|
|
|
|
|
|
|
|
float r,
|
|
|
|
|
|
|
|
float g,
|
|
|
|
|
|
|
|
float b,
|
|
|
|
|
|
|
|
float a,
|
|
|
|
|
|
|
|
uint32_t index,
|
|
|
|
|
|
|
|
UIDrawable* drawable) {
|
|
|
|
|
|
|
|
drawable->pos[0] = x;
|
|
|
|
|
|
|
|
drawable->pos[1] = y;
|
|
|
|
|
|
|
|
drawable->size[0] = width;
|
|
|
|
|
|
|
|
drawable->size[1] = height;
|
|
|
|
|
|
|
|
drawable->color[0] = r;
|
|
|
|
|
|
|
|
drawable->color[1] = g;
|
|
|
|
|
|
|
|
drawable->color[2] = b;
|
|
|
|
|
|
|
|
drawable->color[3] = a;
|
|
|
|
|
|
|
|
drawable->type = 2;
|
|
|
|
|
|
|
|
drawable->code = index;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void set_ui_string(
|
|
|
|
void set_ui_string(
|
|
|
|
float x,
|
|
|
|
float x,
|
|
|
|
float y,
|
|
|
|
float y,
|
|
|
|