From 1756c33c9b8afd367f5b3e111ec23f2c7d632b2c Mon Sep 17 00:00:00 2001 From: ink-soul Date: Mon, 15 Apr 2024 17:58:58 +0800 Subject: [PATCH] switch textureloader --- base/VulkanTexture.cpp | 2 + base/VulkanTexture.hpp | 631 ----------------------------------------- base/ui.hpp | 4 +- src/render/render.cpp | 35 +-- src/render/render.h | 2 +- 5 files changed, 24 insertions(+), 650 deletions(-) delete mode 100644 base/VulkanTexture.hpp diff --git a/base/VulkanTexture.cpp b/base/VulkanTexture.cpp index 039cf59..32c815d 100644 --- a/base/VulkanTexture.cpp +++ b/base/VulkanTexture.cpp @@ -79,6 +79,7 @@ namespace vks ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture); // Get device properties for the requested texture format + VkFormatProperties formatProperties; vkGetPhysicalDeviceFormatProperties(device->physicalDevice, format, &formatProperties); @@ -87,6 +88,7 @@ namespace vks // optimal tiling instead // On most implementations linear tiling will only support a very // limited amount of formats and features (mip maps, cubemaps, arrays, etc.) + VkBool32 useStaging = !forceLinear; VkMemoryAllocateInfo memAllocInfo = vks::initializers::memoryAllocateInfo(); diff --git a/base/VulkanTexture.hpp b/base/VulkanTexture.hpp deleted file mode 100644 index bca7d7e..0000000 --- a/base/VulkanTexture.hpp +++ /dev/null @@ -1,631 +0,0 @@ -/* -* Vulkan texture loader -* -* Copyright(C) 2016-2017 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license(MIT) (http://opensource.org/licenses/MIT) -*/ - -#pragma once - -#include -#include -#include -#include - -#include "vulkan/vulkan.h" -#include "VulkanTools.h" -#include "VulkanDevice.hpp" -#define GLM_ENABLE_EXPERIMENTAL -#include - - -namespace vks -{ - class Texture { - public: - vks::VulkanDevice *device; - VkImage image = VK_NULL_HANDLE; - VkImageLayout imageLayout; - VkDeviceMemory deviceMemory; - VkImageView view; - uint32_t width, height; - uint32_t mipLevels; - uint32_t layerCount; - VkDescriptorImageInfo descriptor; - VkSampler sampler; - - void updateDescriptor() - { - descriptor.sampler = sampler; - descriptor.imageView = view; - descriptor.imageLayout = imageLayout; - } - - void destroy() - { - vkDestroyImageView(device->logicalDevice, view, nullptr); - vkDestroyImage(device->logicalDevice, image, nullptr); - if (sampler) - { - vkDestroySampler(device->logicalDevice, sampler, nullptr); - } - vkFreeMemory(device->logicalDevice, deviceMemory, nullptr); - } - }; - - class Texture2D : public Texture { - public: - void loadFromFile( - std::string filename, - VkFormat format, - vks::VulkanDevice *device, - VkQueue copyQueue, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - - gli::texture2d tex2D(gli::load(filename.c_str())); - - assert(!tex2D.empty()); - - this->device = device; - width = static_cast(tex2D[0].extent().x); - height = static_cast(tex2D[0].extent().y); - mipLevels = static_cast(tex2D.levels()); - - // Get device properites for the requested texture format - VkFormatProperties formatProperties; - vkGetPhysicalDeviceFormatProperties(device->physicalDevice, format, &formatProperties); - - - VkMemoryAllocateInfo texMemAllocInfo{}; - texMemAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - VkMemoryRequirements memReqs; - - // Use a separate command buffer for texture loading - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Create a host-visible staging buffer that contains the raw image data - VkBuffer stagingBuffer; - VkDeviceMemory stagingMemory; - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = tex2D.size(); - // This buffer is used as a transfer source for the buffer copy - bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - VK_CHECK_RESULT(vkCreateBuffer(device->logicalDevice, &bufferCreateInfo, nullptr, &stagingBuffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - - texMemAllocInfo.allocationSize = memReqs.size; - // Get memory type index for a host visible buffer - texMemAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &texMemAllocInfo, nullptr, &stagingMemory)); - VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); - - // Copy texture data into staging buffer - uint8_t *data; - VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data)); - memcpy(data, tex2D.data(), tex2D.size()); - vkUnmapMemory(device->logicalDevice, stagingMemory); - - // Setup buffer copy regions for each mip level - std::vector bufferCopyRegions; - uint32_t offset = 0; - - for (uint32_t i = 0; i < mipLevels; i++) - { - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferCopyRegion.imageSubresource.mipLevel = i; - bufferCopyRegion.imageSubresource.baseArrayLayer = 0; - bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = static_cast(tex2D[i].extent().x); - bufferCopyRegion.imageExtent.height = static_cast(tex2D[i].extent().y); - bufferCopyRegion.imageExtent.depth = 1; - bufferCopyRegion.bufferOffset = offset; - - bufferCopyRegions.push_back(bufferCopyRegion); - - offset += static_cast(tex2D[i].size()); - } - - // Create optimal tiled target image - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = mipLevels; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.extent = { width, height, 1 }; - imageCreateInfo.usage = imageUsageFlags; - // Ensure that the TRANSFER_DST bit is set for staging - if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - { - imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; - } - VK_CHECK_RESULT(vkCreateImage(device->logicalDevice, &imageCreateInfo, nullptr, &image)); - - vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - - texMemAllocInfo.allocationSize = memReqs.size; - - texMemAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &texMemAllocInfo, nullptr, &deviceMemory)); - VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); - - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = mipLevels; - subresourceRange.layerCount = 1; - - // Image barrier for optimal image (target) - // Optimal image will be used as destination for the copy - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - // Copy mip levels from staging buffer - vkCmdCopyBufferToImage( - copyCmd, - stagingBuffer, - image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(bufferCopyRegions.size()), - bufferCopyRegions.data() - ); - - // Change texture image layout to shader read after all mip levels have been copied - this->imageLayout = imageLayout; - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = imageLayout; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - device->flushCommandBuffer(copyCmd, copyQueue); - - // Clean up staging resources - vkFreeMemory(device->logicalDevice, stagingMemory, nullptr); - vkDestroyBuffer(device->logicalDevice, stagingBuffer, nullptr); - - VkSamplerCreateInfo samplerCreateInfo{}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = VK_FILTER_LINEAR; - samplerCreateInfo.minFilter = VK_FILTER_LINEAR; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.mipLodBias = 0.0f; - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - samplerCreateInfo.minLod = 0.0f; - samplerCreateInfo.maxLod = (float)mipLevels; - samplerCreateInfo.maxAnisotropy = device->enabledFeatures.samplerAnisotropy ? device->properties.limits.maxSamplerAnisotropy : 1.0f; - samplerCreateInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy; - samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler)); - - VkImageViewCreateInfo viewCreateInfo{}; - viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewCreateInfo.format = format; - viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - viewCreateInfo.subresourceRange.levelCount = mipLevels; - viewCreateInfo.image = image; - VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view)); - - updateDescriptor(); - } - - void loadFromBuffer( - void* buffer, - VkDeviceSize bufferSize, - VkFormat format, - uint32_t width, - uint32_t height, - vks::VulkanDevice *device, - VkQueue copyQueue, - VkFilter filter = VK_FILTER_LINEAR, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - assert(buffer); - - this->device = device; - width = width; - height = height; - mipLevels = 1; - - VkMemoryAllocateInfo memAllocInfo{}; - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - VkMemoryRequirements memReqs; - // Use a separate command buffer for texture loading - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Create a host-visible staging buffer that contains the raw image data - VkBuffer stagingBuffer; - VkDeviceMemory stagingMemory; - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = bufferSize; - // This buffer is used as a transfer source for the buffer copy - bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - VK_CHECK_RESULT(vkCreateBuffer(device->logicalDevice, &bufferCreateInfo, nullptr, &stagingBuffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - // Get memory type index for a host visible buffer - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &stagingMemory)); - VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); - - // Copy texture data into staging buffer - uint8_t *data; - VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data)); - memcpy(data, buffer, bufferSize); - vkUnmapMemory(device->logicalDevice, stagingMemory); - - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferCopyRegion.imageSubresource.mipLevel = 0; - bufferCopyRegion.imageSubresource.baseArrayLayer = 0; - bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = width; - bufferCopyRegion.imageExtent.height = height; - bufferCopyRegion.imageExtent.depth = 1; - bufferCopyRegion.bufferOffset = 0; - - // Create optimal tiled target image - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = mipLevels; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.extent = { width, height, 1 }; - imageCreateInfo.usage = imageUsageFlags; - // Ensure that the TRANSFER_DST bit is set for staging - if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - { - imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; - } - VK_CHECK_RESULT(vkCreateImage(device->logicalDevice, &imageCreateInfo, nullptr, &image)); - - vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &deviceMemory)); - VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); - - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = mipLevels; - subresourceRange.layerCount = 1; - - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - vkCmdCopyBufferToImage( - copyCmd, - stagingBuffer, - image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, - &bufferCopyRegion - ); - - this->imageLayout = imageLayout; - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = imageLayout; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - device->flushCommandBuffer(copyCmd, copyQueue); - - // Clean up staging resources - vkFreeMemory(device->logicalDevice, stagingMemory, nullptr); - vkDestroyBuffer(device->logicalDevice, stagingBuffer, nullptr); - - // Create sampler - VkSamplerCreateInfo samplerCreateInfo = {}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = filter; - samplerCreateInfo.minFilter = filter; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.mipLodBias = 0.0f; - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - samplerCreateInfo.minLod = 0.0f; - samplerCreateInfo.maxLod = 0.0f; - samplerCreateInfo.maxAnisotropy = 1.0f; - VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler)); - - // Create image view - VkImageViewCreateInfo viewCreateInfo = {}; - viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewCreateInfo.pNext = NULL; - viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewCreateInfo.format = format; - viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - viewCreateInfo.subresourceRange.levelCount = 1; - viewCreateInfo.image = image; - VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view)); - - // Update descriptor image info member that can be used for setting up descriptor sets - updateDescriptor(); - } - }; - - class TextureCubeMap : public Texture { - public: - void loadFromFile( - std::string filename, - VkFormat format, - vks::VulkanDevice *device, - VkQueue copyQueue, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { -#if defined(__ANDROID__) - // Textures are stored inside the apk on Android (compressed) - // So they need to be loaded via the asset manager - AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); - if (!asset) { - LOGE("Could not load texture %s", filename.c_str()); - exit(-1); - } - size_t size = AAsset_getLength(asset); - assert(size > 0); - - void *textureData = malloc(size); - AAsset_read(asset, textureData, size); - AAsset_close(asset); - - gli::texture_cube texCube(gli::load((const char*)textureData, size)); - - free(textureData); -#else - gli::texture_cube texCube(gli::load(filename)); -#endif - assert(!texCube.empty()); - - this->device = device; - width = static_cast(texCube.extent().x); - height = static_cast(texCube.extent().y); - mipLevels = static_cast(texCube.levels()); - - VkMemoryAllocateInfo memAllocInfo{}; - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - VkMemoryRequirements memReqs; - - // Create a host-visible staging buffer that contains the raw image data - VkBuffer stagingBuffer; - VkDeviceMemory stagingMemory; - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = texCube.size(); - // This buffer is used as a transfer source for the buffer copy - bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - VK_CHECK_RESULT(vkCreateBuffer(device->logicalDevice, &bufferCreateInfo, nullptr, &stagingBuffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - // Get memory type index for a host visible buffer - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &stagingMemory)); - VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); - - // Copy texture data into staging buffer - uint8_t *data; - VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data)); - memcpy(data, texCube.data(), texCube.size()); - vkUnmapMemory(device->logicalDevice, stagingMemory); - - // Setup buffer copy regions for each face including all of it's miplevels - std::vector bufferCopyRegions; - size_t offset = 0; - - for (uint32_t face = 0; face < 6; face++) { - for (uint32_t level = 0; level < mipLevels; level++) { - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferCopyRegion.imageSubresource.mipLevel = level; - bufferCopyRegion.imageSubresource.baseArrayLayer = face; - bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = static_cast(texCube[face][level].extent().x); - bufferCopyRegion.imageExtent.height = static_cast(texCube[face][level].extent().y); - bufferCopyRegion.imageExtent.depth = 1; - bufferCopyRegion.bufferOffset = offset; - - bufferCopyRegions.push_back(bufferCopyRegion); - - // Increase offset into staging buffer for next level / face - offset += texCube[face][level].size(); - } - } - - // Create optimal tiled target image - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = mipLevels; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.extent = { width, height, 1 }; - imageCreateInfo.usage = imageUsageFlags; - // Ensure that the TRANSFER_DST bit is set for staging - if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { - imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; - } - // Cube faces count as array layers in Vulkan - imageCreateInfo.arrayLayers = 6; - // This flag is required for cube map images - imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - - - VK_CHECK_RESULT(vkCreateImage(device->logicalDevice, &imageCreateInfo, nullptr, &image)); - - vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &deviceMemory)); - VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); - - // Use a separate command buffer for texture loading - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Image barrier for optimal image (target) - // Set initial layout for all array layers (faces) of the optimal (target) tiled texture - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = mipLevels; - subresourceRange.layerCount = 6; - - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - // Copy the cube map faces from the staging buffer to the optimal tiled image - vkCmdCopyBufferToImage( - copyCmd, - stagingBuffer, - image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(bufferCopyRegions.size()), - bufferCopyRegions.data()); - - // Change texture image layout to shader read after all faces have been copied - this->imageLayout = imageLayout; - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = imageLayout; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - device->flushCommandBuffer(copyCmd, copyQueue); - - // Create sampler - VkSamplerCreateInfo samplerCreateInfo{}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = VK_FILTER_LINEAR; - samplerCreateInfo.minFilter = VK_FILTER_LINEAR; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU; - samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU; - samplerCreateInfo.mipLodBias = 0.0f; - samplerCreateInfo.maxAnisotropy = device->enabledFeatures.samplerAnisotropy ? device->properties.limits.maxSamplerAnisotropy : 1.0f; - samplerCreateInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy; - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - samplerCreateInfo.minLod = 0.0f; - samplerCreateInfo.maxLod = (float)mipLevels; - samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler)); - - // Create image view - VkImageViewCreateInfo viewCreateInfo{}; - viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE; - viewCreateInfo.format = format; - viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - viewCreateInfo.subresourceRange.layerCount = 6; - viewCreateInfo.subresourceRange.levelCount = mipLevels; - viewCreateInfo.image = image; - VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view)); - - // Clean up staging resources - vkFreeMemory(device->logicalDevice, stagingMemory, nullptr); - vkDestroyBuffer(device->logicalDevice, stagingBuffer, nullptr); - - // Update descriptor image info member that can be used for setting up descriptor sets - updateDescriptor(); - } - }; - -} \ No newline at end of file diff --git a/base/ui.hpp b/base/ui.hpp index fe4340c..0647742 100644 --- a/base/ui.hpp +++ b/base/ui.hpp @@ -7,7 +7,7 @@ #include "imgui/imgui.h" #include "VulkanDevice.hpp" #include "VulkanUtils.hpp" -#include "VulkanTexture.hpp" +#include "VulkanTexture.h" #if defined(__ANDROID__) #include @@ -64,7 +64,7 @@ public: io.Fonts->AddFontFromFileTTF(ttfFilePath.data(), 16.0f,NULL, io.Fonts->GetGlyphRangesChineseSimplifiedCommon()); #endif io.Fonts->GetTexDataAsRGBA32(&fontData, &texWidth, &texHeight); - fontTexture.loadFromBuffer(fontData, texWidth * texHeight * 4 * sizeof(char), VK_FORMAT_R8G8B8A8_UNORM, texWidth, texHeight, vulkanDevice, queue); + fontTexture.fromBuffer(fontData, texWidth * texHeight * 4 * sizeof(char), VK_FORMAT_R8G8B8A8_UNORM, texWidth, texHeight, vulkanDevice, queue); /* Setup diff --git a/src/render/render.cpp b/src/render/render.cpp index e1e8de6..7e83d05 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -694,11 +694,10 @@ void PlumageRender::createImageView() VkMemoryAllocateInfo memAllocInfo{}; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.allocationSize = memReqs.size; - VkBool32 lazyMemTypePresent; - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); - if (!lazyMemTypePresent) { - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } + + + memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.colorAttachment.memory)); vkBindImageMemory(device, multisampleTarget.colorAttachment.image, multisampleTarget.colorAttachment.memory, 0); @@ -735,10 +734,9 @@ void PlumageRender::createImageView() vkGetImageMemoryRequirements(device, multisampleTarget.depthAttachment.image, &memReqs); memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.allocationSize = memReqs.size; - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); - if (!lazyMemTypePresent) { - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } + + memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.depthAttachment.memory)); vkBindImageMemory(device, multisampleTarget.depthAttachment.image, multisampleTarget.depthAttachment.memory, 0); @@ -1220,8 +1218,7 @@ void PlumageRender::loadAssets() readDirectory(assetpath + "environments", "*.ktx", environments, false); - textures.empty.loadFromFile(PlumageRender::filePath.emptyEnvmapFilePath, VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, graphicQueue); - + std::string sceneFile = filePath.glTFModelFilePath; std::string envMapFile = filePath.envMapFilePath; for (size_t i = 0; i < args.size(); i++) { @@ -1245,9 +1242,13 @@ void PlumageRender::loadAssets() } } - loadScene(sceneFile.c_str()); - models.skybox.loadFromFile(PlumageRender::filePath.skyboxModleFilePath, vulkanDevice, graphicQueue); + + + models.skybox.loadFromFile(PlumageRender::filePath.skyboxModleFilePath, vulkanDevice, graphicQueue); + loadScene(sceneFile.c_str()); + + textures.empty.loadFromFile(PlumageRender::filePath.emptyEnvmapFilePath, VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, graphicQueue); loadEnvironment(envMapFile.c_str()); } @@ -2542,9 +2543,10 @@ void PlumageRender::prepare() createPipelineCache(); createImageView(); - createFramebuffer(); + + camera.type = Camera::CameraType::lookat; camera.setPerspective(45.0f, (float)settings.width / (float)settings.height, 0.1f, 256.0f); @@ -2582,14 +2584,15 @@ void PlumageRender::prepare() VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commandBuffers.data())); } - + + loadAssets(); generateBRDFLUT(); generateCubemaps(); prepareUniformBuffers(); setupDescriptors(); preparePipelines(); - + //gui = new UI(vulkanDevice, renderPass, graphicQueue, pipelineCache, settings.sampleCount); //updateUIOverlay(); diff --git a/src/render/render.h b/src/render/render.h index f7c7e09..18560ac 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -38,7 +38,7 @@ #include //#include "VulkanExampleBase.h" #include "glTFModel.h" -#include +#include #include "VulkanDevice.hpp" #include "ui.hpp" #include