Added some string functions and macros Added path listing on windows Added assets
120 lines
3.7 KiB
C
120 lines
3.7 KiB
C
|
|
void G_ImagesLoad(M_Arena *arena) {
|
|
M_TempScope(1, &arena) {
|
|
FS_List assets = FS_PathList(temp.arena, S("assets"));
|
|
|
|
Vk_Buffer staging = Vk_BufferCreate(MB(256), true /* host_visible */);
|
|
|
|
U8 *base = staging.data;
|
|
U64 offset = 0;
|
|
|
|
Vk_CommandBuffer *cmds = Vk_CommandBufferPush();
|
|
|
|
U32 n_images = 0;
|
|
|
|
for (FS_Entry *it = assets.first; it != 0; it = it->next) {
|
|
if (Str8_EndsWith(it->basename, S("png"))) {
|
|
n_images += 1;
|
|
}
|
|
}
|
|
|
|
VkBufferImageCopy copy = { 0 };
|
|
G_Image *images = M_ArenaPush(arena, G_Image, .count = n_images);
|
|
n_images = 0;
|
|
|
|
// Image upload is sbi_load -> copy to staging -> upload to gpu texture
|
|
|
|
for (FS_Entry *it = assets.first; it != 0; it = it->next) {
|
|
if (Str8_EndsWith(it->basename, S("png"))) {
|
|
S32 w, h, c;
|
|
stbi_uc *data = stbi_load((const char *) it->path.data, &w, &h, &c, 4);
|
|
|
|
if (data) {
|
|
G_Image *image = &images[n_images];
|
|
|
|
U64 image_sz = 4 * w * h;
|
|
|
|
M_CopySize(base, data, image_sz);
|
|
|
|
copy.bufferOffset = offset;
|
|
copy.bufferRowLength = 0;
|
|
copy.bufferImageHeight = 0;
|
|
|
|
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
copy.imageSubresource.mipLevel = 0;
|
|
copy.imageSubresource.baseArrayLayer = 0;
|
|
copy.imageSubresource.layerCount = 1;
|
|
|
|
copy.imageExtent.width = w;
|
|
copy.imageExtent.height = h;
|
|
copy.imageExtent.depth = 1;
|
|
|
|
base += image_sz;
|
|
offset += image_sz;
|
|
|
|
Assert(offset <= staging.size);
|
|
|
|
n_images += 1;
|
|
|
|
image->name = Str8_Copy(arena, Str8_RemoveAfterLast(it->basename, '.'));
|
|
|
|
image->image.width = w;
|
|
image->image.height = h;
|
|
|
|
image->image.format = VK_FORMAT_R8G8B8A8_SRGB;
|
|
image->image.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
Vk_ImageCreate(&image->image);
|
|
|
|
VkImageMemoryBarrier2 transfer = { 0 };
|
|
VkImageMemoryBarrier2 shader_read = { 0 };
|
|
|
|
transfer.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
|
transfer.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
|
|
transfer.srcAccessMask = VK_ACCESS_2_NONE;
|
|
transfer.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
|
transfer.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
|
transfer.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
transfer.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
transfer.image = image->image.handle;
|
|
|
|
transfer.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
transfer.subresourceRange.layerCount = 1;
|
|
transfer.subresourceRange.levelCount = 1;
|
|
|
|
shader_read.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
|
shader_read.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
|
shader_read.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
|
shader_read.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
|
|
shader_read.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
|
|
shader_read.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
shader_read.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
shader_read.image = image->image.handle;
|
|
|
|
shader_read.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
shader_read.subresourceRange.layerCount = 1;
|
|
shader_read.subresourceRange.levelCount = 1;
|
|
|
|
VkDependencyInfo dep = { 0 };
|
|
dep.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
|
|
|
dep.imageMemoryBarrierCount = 1;
|
|
dep.pImageMemoryBarriers = &transfer;
|
|
|
|
vk.CmdPipelineBarrier2(cmds->handle, &dep);
|
|
|
|
vk.CmdCopyBufferToImage(cmds->handle, staging.handle, image->image.handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
|
|
|
dep.pImageMemoryBarriers = &shader_read;
|
|
|
|
vk.CmdPipelineBarrier2(cmds->handle, &dep);
|
|
|
|
stbi_image_free(data);
|
|
}
|
|
}
|
|
}
|
|
|
|
Vk_CommandBufferSubmit(cmds, true /* wait */);
|
|
}
|
|
}
|