Add GEVulkanArrayTexture
This commit is contained in:
parent
694c1b6c29
commit
5aa70333ce
@ -71,6 +71,7 @@ set(GE_SOURCES
|
|||||||
src/ge_texture.cpp
|
src/ge_texture.cpp
|
||||||
src/ge_vma.cpp
|
src/ge_vma.cpp
|
||||||
src/ge_vulkan_2d_renderer.cpp
|
src/ge_vulkan_2d_renderer.cpp
|
||||||
|
src/ge_vulkan_array_texture.cpp
|
||||||
src/ge_vulkan_animated_mesh_scene_node.cpp
|
src/ge_vulkan_animated_mesh_scene_node.cpp
|
||||||
src/ge_vulkan_camera_scene_node.cpp
|
src/ge_vulkan_camera_scene_node.cpp
|
||||||
src/ge_vulkan_command_loader.cpp
|
src/ge_vulkan_command_loader.cpp
|
||||||
|
245
lib/graphics_engine/src/ge_vulkan_array_texture.cpp
Normal file
245
lib/graphics_engine/src/ge_vulkan_array_texture.cpp
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
#include "ge_vulkan_array_texture.hpp"
|
||||||
|
|
||||||
|
#include "ge_main.hpp"
|
||||||
|
#include "ge_mipmap_generator.hpp"
|
||||||
|
#include "ge_compressor_astc_4x4.hpp"
|
||||||
|
#include "ge_compressor_s3tc_bc3.hpp"
|
||||||
|
#include "ge_texture.hpp"
|
||||||
|
#include "ge_vulkan_command_loader.hpp"
|
||||||
|
#include "ge_vulkan_driver.hpp"
|
||||||
|
#include "ge_vulkan_features.hpp"
|
||||||
|
|
||||||
|
#include <IImageLoader.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace GE
|
||||||
|
{
|
||||||
|
// ============================================================================
|
||||||
|
std::vector<io::path> getPathList(const std::vector<GEVulkanTexture*>& tlist)
|
||||||
|
{
|
||||||
|
std::vector<io::path> list;
|
||||||
|
for (GEVulkanTexture* tex : tlist)
|
||||||
|
list.push_back(tex->getFullPath());
|
||||||
|
return list;
|
||||||
|
} // getPathList
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
GEVulkanArrayTexture::GEVulkanArrayTexture(const std::vector<io::path>& list,
|
||||||
|
VkImageViewType type,
|
||||||
|
std::function<void(video::IImage*,
|
||||||
|
unsigned)> image_mani)
|
||||||
|
: GEVulkanTexture()
|
||||||
|
{
|
||||||
|
if (list.empty())
|
||||||
|
throw std::runtime_error("empty texture list for array texture");
|
||||||
|
|
||||||
|
m_layer_count = list.size();
|
||||||
|
m_image_view_type = type;
|
||||||
|
m_vk = getVKDriver();
|
||||||
|
m_vulkan_device = m_vk->getDevice();
|
||||||
|
m_image = VK_NULL_HANDLE;
|
||||||
|
m_vma_allocation = VK_NULL_HANDLE;
|
||||||
|
m_has_mipmaps = true;
|
||||||
|
m_locked_data = NULL;
|
||||||
|
m_max_size = m_vk->getDriverAttributes()
|
||||||
|
.getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||||
|
m_internal_format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
m_texture_size = 0;
|
||||||
|
|
||||||
|
m_size_lock.lock();
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
GEVulkanCommandLoader::addMultiThreadingCommand(
|
||||||
|
[list, image_mani, this]()
|
||||||
|
{
|
||||||
|
reloadInternal(list, image_mani);
|
||||||
|
});
|
||||||
|
} // GEVulkanArrayTexture
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GEVulkanArrayTexture::GEVulkanArrayTexture(
|
||||||
|
const std::vector<GEVulkanTexture*>& textures,
|
||||||
|
VkImageViewType type,
|
||||||
|
std::function<void(video::IImage*, unsigned)>
|
||||||
|
image_mani)
|
||||||
|
: GEVulkanArrayTexture(getPathList(textures), type,
|
||||||
|
image_mani)
|
||||||
|
{
|
||||||
|
} // GEVulkanArrayTexture
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GEVulkanArrayTexture::reloadInternal(const std::vector<io::path>& list,
|
||||||
|
std::function<void(video::IImage*,
|
||||||
|
unsigned)> image_mani)
|
||||||
|
{
|
||||||
|
VkDeviceSize image_size = 0;
|
||||||
|
VkDeviceSize mipmap_data_size = 0;
|
||||||
|
VkDeviceSize image_total_size = 0;
|
||||||
|
std::vector<video::IImage*> images;
|
||||||
|
std::vector<GEMipmapGenerator*> mipmaps;
|
||||||
|
|
||||||
|
VkBuffer staging_buffer = NULL;
|
||||||
|
VmaAllocation staging_buffer_allocation = NULL;
|
||||||
|
VmaAllocationCreateInfo staging_buffer_create_info = {};
|
||||||
|
staging_buffer_create_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
|
staging_buffer_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||||
|
staging_buffer_create_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||||
|
|
||||||
|
assert(m_layer_count == list.size());
|
||||||
|
uint8_t* mapped;
|
||||||
|
VkCommandBuffer command_buffer = VK_NULL_HANDLE;
|
||||||
|
unsigned offset = 0;
|
||||||
|
unsigned width = 0;
|
||||||
|
unsigned height = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < list.size(); i++)
|
||||||
|
{
|
||||||
|
const io::path& fullpath = list[i];
|
||||||
|
video::IImageLoader* loader = NULL;
|
||||||
|
io::IReadFile* file = io::createReadFile(fullpath);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
printf("Missing file %s in GEVulkanArrayTexture::reloadInternal",
|
||||||
|
fullpath.c_str());
|
||||||
|
goto destroy;
|
||||||
|
}
|
||||||
|
m_vk->createImageFromFile(file, &loader);
|
||||||
|
core::dimension2du dim;
|
||||||
|
if (!loader || !loader->getImageSize(file, &dim))
|
||||||
|
{
|
||||||
|
file->drop();
|
||||||
|
printf("Missing image loader for %s in "
|
||||||
|
"GEVulkanArrayTexture::reloadInternal", fullpath.c_str());
|
||||||
|
goto destroy;
|
||||||
|
}
|
||||||
|
file->drop();
|
||||||
|
if (m_image_view_type == VK_IMAGE_VIEW_TYPE_CUBE ||
|
||||||
|
m_image_view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||||
|
{
|
||||||
|
width = std::max({ width, dim.Width, dim.Height });
|
||||||
|
height = width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = std::max(width, dim.Width);
|
||||||
|
height = std::max(height, dim.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size = core::dimension2du(width, height);
|
||||||
|
image_size = m_size.Width * m_size.Height * 4;
|
||||||
|
m_orig_size = m_size;
|
||||||
|
m_size_lock.unlock();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < list.size(); i++)
|
||||||
|
{
|
||||||
|
const io::path& fullpath = list[i];
|
||||||
|
video::IImage* texture_image = getResizedImageFullPath(fullpath,
|
||||||
|
m_max_size, NULL, &m_size);
|
||||||
|
if (texture_image == NULL)
|
||||||
|
goto destroy;
|
||||||
|
if (image_mani)
|
||||||
|
image_mani(texture_image, i);
|
||||||
|
uint8_t* texture_data = (uint8_t*)texture_image->lock();
|
||||||
|
bgraConversion(texture_data);
|
||||||
|
GEMipmapGenerator* mipmap_generator = NULL;
|
||||||
|
const bool normal_map = (std::string(fullpath.c_str()).find(
|
||||||
|
"_Normal.") != std::string::npos);
|
||||||
|
bool texture_compression = getGEConfig()->m_texture_compression;
|
||||||
|
if (texture_compression && GEVulkanFeatures::supportsASTC4x4())
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||||
|
m_size.Height);
|
||||||
|
m_internal_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
|
||||||
|
}
|
||||||
|
mipmap_generator = new GECompressorASTC4x4(texture_data, 4, m_size,
|
||||||
|
normal_map);
|
||||||
|
}
|
||||||
|
else if (texture_compression && GEVulkanFeatures::supportsS3TCBC3())
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||||
|
m_size.Height);
|
||||||
|
m_internal_format = VK_FORMAT_BC3_UNORM_BLOCK;
|
||||||
|
}
|
||||||
|
mipmap_generator = new GECompressorS3TCBC3(texture_data, 4, m_size,
|
||||||
|
normal_map);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mipmap_generator = new GEMipmapGenerator(texture_data, 4, m_size,
|
||||||
|
normal_map);
|
||||||
|
}
|
||||||
|
mipmap_data_size = mipmap_generator->getMipmapSizes();
|
||||||
|
if (mipmaps.empty())
|
||||||
|
{
|
||||||
|
image_total_size = image_size + mipmap_data_size;
|
||||||
|
image_total_size *= m_layer_count;
|
||||||
|
if (!m_vk->createBuffer(image_total_size,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, staging_buffer_create_info,
|
||||||
|
staging_buffer, staging_buffer_allocation))
|
||||||
|
{
|
||||||
|
goto destroy;
|
||||||
|
}
|
||||||
|
if (vmaMapMemory(m_vk->getVmaAllocator(),
|
||||||
|
staging_buffer_allocation, (void**)&mapped) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
goto destroy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mipmaps.push_back(mipmap_generator);
|
||||||
|
for (GEImageLevel& level : mipmap_generator->getAllLevels())
|
||||||
|
{
|
||||||
|
memcpy(mapped, level.m_data, level.m_size);
|
||||||
|
mapped += level.m_size;
|
||||||
|
}
|
||||||
|
images.push_back(texture_image);
|
||||||
|
}
|
||||||
|
vmaUnmapMemory(m_vk->getVmaAllocator(), staging_buffer_allocation);
|
||||||
|
vmaFlushAllocation(m_vk->getVmaAllocator(),
|
||||||
|
staging_buffer_allocation, 0, image_total_size);
|
||||||
|
|
||||||
|
if (!createImage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||||
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT))
|
||||||
|
goto destroy;
|
||||||
|
|
||||||
|
command_buffer = GEVulkanCommandLoader::beginSingleTimeCommands();
|
||||||
|
|
||||||
|
transitionImageLayout(command_buffer, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < list.size(); i++)
|
||||||
|
{
|
||||||
|
std::vector<GEImageLevel>& levels = mipmaps[i]->getAllLevels();
|
||||||
|
for (unsigned j = 0; j < levels.size(); j++)
|
||||||
|
{
|
||||||
|
GEImageLevel& level = levels[j];
|
||||||
|
copyBufferToImage(command_buffer, staging_buffer,
|
||||||
|
level.m_dim.Width, level.m_dim.Height, 0, 0, offset, j, i);
|
||||||
|
offset += level.m_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transitionImageLayout(command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
|
GEVulkanCommandLoader::endSingleTimeCommands(command_buffer);
|
||||||
|
|
||||||
|
createImageView(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
|
||||||
|
destroy:
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
for (video::IImage* image : images)
|
||||||
|
image->drop();
|
||||||
|
for (GEMipmapGenerator* mipmap_generator : mipmaps)
|
||||||
|
delete mipmap_generator;
|
||||||
|
if (staging_buffer != VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
vmaDestroyBuffer(m_vk->getVmaAllocator(), staging_buffer,
|
||||||
|
staging_buffer_allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // reloadInternal
|
||||||
|
|
||||||
|
}
|
57
lib/graphics_engine/src/ge_vulkan_array_texture.hpp
Normal file
57
lib/graphics_engine/src/ge_vulkan_array_texture.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef HEADER_GE_VULKAN_ARRAY_TEXTURE_HPP
|
||||||
|
#define HEADER_GE_VULKAN_ARRAY_TEXTURE_HPP
|
||||||
|
|
||||||
|
#include "ge_vulkan_texture.hpp"
|
||||||
|
|
||||||
|
namespace GE
|
||||||
|
{
|
||||||
|
class GEVulkanDriver;
|
||||||
|
class GEVulkanArrayTexture : public GEVulkanTexture
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void reloadInternal(const std::vector<io::path>& list,
|
||||||
|
std::function<void(video::IImage*, unsigned)>
|
||||||
|
image_mani);
|
||||||
|
public:
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
GEVulkanArrayTexture(const std::vector<io::path>& full_path_list,
|
||||||
|
VkImageViewType type,
|
||||||
|
std::function<void(video::IImage*, unsigned)>
|
||||||
|
image_mani = nullptr);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
GEVulkanArrayTexture(const std::vector<GEVulkanTexture*>& textures,
|
||||||
|
VkImageViewType type,
|
||||||
|
std::function<void(video::IImage*, unsigned)>
|
||||||
|
image_mani = nullptr);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual ~GEVulkanArrayTexture() {}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void* lock(video::E_TEXTURE_LOCK_MODE mode =
|
||||||
|
video::ETLM_READ_WRITE, u32 mipmap_level = 0)
|
||||||
|
{ return NULL; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void unlock() {}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual video::E_DRIVER_TYPE getDriverType() const
|
||||||
|
{ return video::EDT_VULKAN; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual video::ECOLOR_FORMAT getColorFormat() const
|
||||||
|
{ return video::ECF_A8R8G8B8; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual u32 getPitch() const { return 0; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual bool hasMipMaps() const { return false; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void regenerateMipMapLevels(void* mipmap_data = NULL) {}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual unsigned int getTextureSize() const { return m_texture_size; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void reload() {}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void updateTexture(void* data, irr::video::ECOLOR_FORMAT format,
|
||||||
|
u32 w, u32 h, u32 x, u32 y) {}
|
||||||
|
}; // GEVulkanArrayTexture
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -28,9 +28,10 @@ GEVulkanTexture::GEVulkanTexture(const std::string& path,
|
|||||||
m_locked_data(NULL),
|
m_locked_data(NULL),
|
||||||
m_vulkan_device(getVKDriver()->getDevice()),
|
m_vulkan_device(getVKDriver()->getDevice()),
|
||||||
m_image(VK_NULL_HANDLE), m_vma_allocation(VK_NULL_HANDLE),
|
m_image(VK_NULL_HANDLE), m_vma_allocation(VK_NULL_HANDLE),
|
||||||
m_texture_size(0), m_disable_reload(false),
|
m_texture_size(0), m_layer_count(1),
|
||||||
m_has_mipmaps(true), m_ondemand_load(false),
|
m_image_view_type(VK_IMAGE_VIEW_TYPE_2D),
|
||||||
m_ondemand_loading(false),
|
m_disable_reload(false), m_has_mipmaps(true),
|
||||||
|
m_ondemand_load(false), m_ondemand_loading(false),
|
||||||
m_internal_format(VK_FORMAT_R8G8B8A8_UNORM),
|
m_internal_format(VK_FORMAT_R8G8B8A8_UNORM),
|
||||||
m_vk(getVKDriver())
|
m_vk(getVKDriver())
|
||||||
{
|
{
|
||||||
@ -75,9 +76,10 @@ GEVulkanTexture::GEVulkanTexture(video::IImage* img, const std::string& name)
|
|||||||
m_locked_data(NULL),
|
m_locked_data(NULL),
|
||||||
m_vulkan_device(getVKDriver()->getDevice()),
|
m_vulkan_device(getVKDriver()->getDevice()),
|
||||||
m_image(VK_NULL_HANDLE), m_vma_allocation(VK_NULL_HANDLE),
|
m_image(VK_NULL_HANDLE), m_vma_allocation(VK_NULL_HANDLE),
|
||||||
m_texture_size(0), m_disable_reload(true),
|
m_texture_size(0), m_layer_count(1),
|
||||||
m_has_mipmaps(true), m_ondemand_load(false),
|
m_image_view_type(VK_IMAGE_VIEW_TYPE_2D),
|
||||||
m_ondemand_loading(false),
|
m_disable_reload(true), m_has_mipmaps(true),
|
||||||
|
m_ondemand_load(false), m_ondemand_loading(false),
|
||||||
m_internal_format(VK_FORMAT_R8G8B8A8_UNORM),
|
m_internal_format(VK_FORMAT_R8G8B8A8_UNORM),
|
||||||
m_vk(getVKDriver())
|
m_vk(getVKDriver())
|
||||||
{
|
{
|
||||||
@ -102,9 +104,10 @@ GEVulkanTexture::GEVulkanTexture(const std::string& name, unsigned int size,
|
|||||||
: video::ITexture(name.c_str()), m_image_mani(nullptr),
|
: video::ITexture(name.c_str()), m_image_mani(nullptr),
|
||||||
m_locked_data(NULL), m_vulkan_device(getVKDriver()->getDevice()),
|
m_locked_data(NULL), m_vulkan_device(getVKDriver()->getDevice()),
|
||||||
m_image(VK_NULL_HANDLE), m_vma_allocation(VK_NULL_HANDLE),
|
m_image(VK_NULL_HANDLE), m_vma_allocation(VK_NULL_HANDLE),
|
||||||
m_texture_size(0), m_disable_reload(true), m_has_mipmaps(true),
|
m_texture_size(0), m_layer_count(1),
|
||||||
m_ondemand_load(false), m_ondemand_loading(false),
|
m_image_view_type(VK_IMAGE_VIEW_TYPE_2D), m_disable_reload(true),
|
||||||
m_internal_format(single_channel ?
|
m_has_mipmaps(true), m_ondemand_load(false),
|
||||||
|
m_ondemand_loading(false), m_internal_format(single_channel ?
|
||||||
VK_FORMAT_R8_UNORM : VK_FORMAT_R8G8B8A8_UNORM),
|
VK_FORMAT_R8_UNORM : VK_FORMAT_R8G8B8A8_UNORM),
|
||||||
m_vk(getVKDriver())
|
m_vk(getVKDriver())
|
||||||
{
|
{
|
||||||
@ -229,14 +232,14 @@ bool GEVulkanTexture::createTextureImage(uint8_t* texture_data,
|
|||||||
{
|
{
|
||||||
GEImageLevel& level = levels[i];
|
GEImageLevel& level = levels[i];
|
||||||
copyBufferToImage(command_buffer, staging_buffer,
|
copyBufferToImage(command_buffer, staging_buffer,
|
||||||
level.m_dim.Width, level.m_dim.Height, 0, 0, offset, i);
|
level.m_dim.Width, level.m_dim.Height, 0, 0, offset, i, 0);
|
||||||
offset += level.m_size;
|
offset += level.m_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
copyBufferToImage(command_buffer, staging_buffer, m_size.Width,
|
copyBufferToImage(command_buffer, staging_buffer, m_size.Width,
|
||||||
m_size.Height, 0, 0, 0, 0);
|
m_size.Height, 0, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
transitionImageLayout(command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
transitionImageLayout(command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
@ -261,13 +264,16 @@ bool GEVulkanTexture::createImage(VkImageUsageFlags usage)
|
|||||||
image_info.extent.height = m_size.Height;
|
image_info.extent.height = m_size.Height;
|
||||||
image_info.extent.depth = 1;
|
image_info.extent.depth = 1;
|
||||||
image_info.mipLevels = getMipmapLevels();
|
image_info.mipLevels = getMipmapLevels();
|
||||||
image_info.arrayLayers = 1;
|
image_info.arrayLayers = m_layer_count;
|
||||||
image_info.format = m_internal_format;
|
image_info.format = m_internal_format;
|
||||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
image_info.usage = usage;
|
image_info.usage = usage;
|
||||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
if (m_image_view_type == VK_IMAGE_VIEW_TYPE_CUBE ||
|
||||||
|
m_image_view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||||
|
image_info.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||||
|
|
||||||
VmaAllocationCreateInfo alloc_info = {};
|
VmaAllocationCreateInfo alloc_info = {};
|
||||||
alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
|
alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
@ -295,7 +301,7 @@ void GEVulkanTexture::transitionImageLayout(VkCommandBuffer command_buffer,
|
|||||||
barrier.subresourceRange.baseMipLevel = 0;
|
barrier.subresourceRange.baseMipLevel = 0;
|
||||||
barrier.subresourceRange.levelCount = getMipmapLevels();
|
barrier.subresourceRange.levelCount = getMipmapLevels();
|
||||||
barrier.subresourceRange.baseArrayLayer = 0;
|
barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
barrier.subresourceRange.layerCount = 1;
|
barrier.subresourceRange.layerCount = m_layer_count;
|
||||||
|
|
||||||
if (new_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
if (new_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||||
{
|
{
|
||||||
@ -376,7 +382,8 @@ void GEVulkanTexture::transitionImageLayout(VkCommandBuffer command_buffer,
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GEVulkanTexture::copyBufferToImage(VkCommandBuffer command_buffer,
|
void GEVulkanTexture::copyBufferToImage(VkCommandBuffer command_buffer,
|
||||||
VkBuffer buffer, u32 w, u32 h, s32 x,
|
VkBuffer buffer, u32 w, u32 h, s32 x,
|
||||||
s32 y, u32 offset, u32 mipmap_level)
|
s32 y, u32 offset, u32 mipmap_level,
|
||||||
|
u32 layer_level)
|
||||||
{
|
{
|
||||||
VkBufferImageCopy region = {};
|
VkBufferImageCopy region = {};
|
||||||
region.bufferOffset = offset;
|
region.bufferOffset = offset;
|
||||||
@ -384,7 +391,7 @@ void GEVulkanTexture::copyBufferToImage(VkCommandBuffer command_buffer,
|
|||||||
region.bufferImageHeight = 0;
|
region.bufferImageHeight = 0;
|
||||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
region.imageSubresource.mipLevel = mipmap_level;
|
region.imageSubresource.mipLevel = mipmap_level;
|
||||||
region.imageSubresource.baseArrayLayer = 0;
|
region.imageSubresource.baseArrayLayer = layer_level;
|
||||||
region.imageSubresource.layerCount = 1;
|
region.imageSubresource.layerCount = 1;
|
||||||
region.imageOffset = {x, y, 0};
|
region.imageOffset = {x, y, 0};
|
||||||
region.imageExtent = {w, h, 1};
|
region.imageExtent = {w, h, 1};
|
||||||
@ -399,13 +406,13 @@ bool GEVulkanTexture::createImageView(VkImageAspectFlags aspect_flags)
|
|||||||
VkImageViewCreateInfo view_info = {};
|
VkImageViewCreateInfo view_info = {};
|
||||||
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
view_info.image = m_image;
|
view_info.image = m_image;
|
||||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
view_info.viewType = m_image_view_type;
|
||||||
view_info.format = m_internal_format;
|
view_info.format = m_internal_format;
|
||||||
view_info.subresourceRange.aspectMask = aspect_flags;
|
view_info.subresourceRange.aspectMask = aspect_flags;
|
||||||
view_info.subresourceRange.baseMipLevel = 0;
|
view_info.subresourceRange.baseMipLevel = 0;
|
||||||
view_info.subresourceRange.levelCount = getMipmapLevels();
|
view_info.subresourceRange.levelCount = getMipmapLevels();
|
||||||
view_info.subresourceRange.baseArrayLayer = 0;
|
view_info.subresourceRange.baseArrayLayer = 0;
|
||||||
view_info.subresourceRange.layerCount = 1;
|
view_info.subresourceRange.layerCount = m_layer_count;
|
||||||
if (isSingleChannel())
|
if (isSingleChannel())
|
||||||
{
|
{
|
||||||
view_info.components.r = VK_COMPONENT_SWIZZLE_ONE;
|
view_info.components.r = VK_COMPONENT_SWIZZLE_ONE;
|
||||||
@ -694,7 +701,7 @@ void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format,
|
|||||||
transitionImageLayout(command_buffer,
|
transitionImageLayout(command_buffer,
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
copyBufferToImage(command_buffer, staging_buffer, w, h, x, y, 0, 0);
|
copyBufferToImage(command_buffer, staging_buffer, w, h, x, y, 0, 0, 0);
|
||||||
|
|
||||||
bool blit_mipmap = true;
|
bool blit_mipmap = true;
|
||||||
if (isSingleChannel() && !GEVulkanFeatures::supportsR8Blit())
|
if (isSingleChannel() && !GEVulkanFeatures::supportsR8Blit())
|
||||||
|
@ -39,6 +39,10 @@ protected:
|
|||||||
|
|
||||||
std::shared_ptr<std::atomic<VkImageView> > m_placeholder_view;
|
std::shared_ptr<std::atomic<VkImageView> > m_placeholder_view;
|
||||||
|
|
||||||
|
unsigned m_layer_count;
|
||||||
|
|
||||||
|
VkImageViewType m_image_view_type;
|
||||||
|
|
||||||
unsigned int m_texture_size;
|
unsigned int m_texture_size;
|
||||||
|
|
||||||
const bool m_disable_reload;
|
const bool m_disable_reload;
|
||||||
@ -72,7 +76,7 @@ protected:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void copyBufferToImage(VkCommandBuffer command_buffer, VkBuffer buffer,
|
void copyBufferToImage(VkCommandBuffer command_buffer, VkBuffer buffer,
|
||||||
u32 w, u32 h, s32 x, s32 y, u32 offset,
|
u32 w, u32 h, s32 x, s32 y, u32 offset,
|
||||||
u32 mipmap_level);
|
u32 mipmap_level, u32 layer_level);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void upload(uint8_t* data, bool generate_hq_mipmap = false);
|
void upload(uint8_t* data, bool generate_hq_mipmap = false);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -114,8 +118,10 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
GEVulkanTexture() : video::ITexture(""), m_disable_reload(true),
|
GEVulkanTexture() : video::ITexture(""), m_layer_count(1),
|
||||||
m_ondemand_load(false), m_ondemand_loading(false) {}
|
m_image_view_type(VK_IMAGE_VIEW_TYPE_2D),
|
||||||
|
m_disable_reload(true), m_ondemand_load(false),
|
||||||
|
m_ondemand_loading(false) {}
|
||||||
public:
|
public:
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
GEVulkanTexture(const std::string& path,
|
GEVulkanTexture(const std::string& path,
|
||||||
|
Loading…
Reference in New Issue
Block a user