Add multithreading GEVulkanTexture loading
This commit is contained in:
parent
059fc9ebfd
commit
5d23d8d790
14
lib/graphics_engine/include/ge_spin_lock.hpp
Normal file
14
lib/graphics_engine/include/ge_spin_lock.hpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef HEADER_GE_SPIN_LOCK_HPP
|
||||||
|
#define HEADER_GE_SPIN_LOCK_HPP
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
class GESpinLock
|
||||||
|
{
|
||||||
|
mutable std::atomic_flag m_locked = ATOMIC_FLAG_INIT;
|
||||||
|
public:
|
||||||
|
void lock() const
|
||||||
|
{ while (m_locked.test_and_set(std::memory_order_acquire)); }
|
||||||
|
void unlock() const { m_locked.clear(std::memory_order_release); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -23,7 +23,17 @@ GEVulkanTexture::GEVulkanTexture(const std::string& path,
|
|||||||
{
|
{
|
||||||
m_max_size = getDriver()->getDriverAttributes()
|
m_max_size = getDriver()->getDriverAttributes()
|
||||||
.getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
.getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||||
reloadInternal();
|
m_full_path = getDriver()->getFileSystem()->getAbsolutePath(NamedPath);
|
||||||
|
if (!getDriver()->getFileSystem()->existFileOnly(m_full_path))
|
||||||
|
{
|
||||||
|
LoadingFailed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size_lock.lock();
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
GEVulkanCommandLoader::addMultiThreadingCommand(
|
||||||
|
std::bind(&GEVulkanTexture::reloadInternal, this));
|
||||||
} // GEVulkanTexture
|
} // GEVulkanTexture
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -69,6 +79,9 @@ GEVulkanTexture::GEVulkanTexture(const std::string& name, unsigned int size,
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
GEVulkanTexture::~GEVulkanTexture()
|
GEVulkanTexture::~GEVulkanTexture()
|
||||||
{
|
{
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
|
||||||
vkDeviceWaitIdle(m_vulkan_device);
|
vkDeviceWaitIdle(m_vulkan_device);
|
||||||
clearVulkanData();
|
clearVulkanData();
|
||||||
} // ~GEVulkanTexture
|
} // ~GEVulkanTexture
|
||||||
@ -349,14 +362,21 @@ void GEVulkanTexture::reloadInternal()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
clearVulkanData();
|
clearVulkanData();
|
||||||
video::IImage* texture_image = getResizedImage(NamedPath.getPtr(),
|
|
||||||
m_max_size, &m_orig_size);
|
io::IReadFile* file = io::createReadFile(m_full_path);
|
||||||
if (texture_image == NULL)
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
LoadingFailed = true;
|
// We checked for file existence so we should always get a file
|
||||||
return;
|
throw std::runtime_error("File missing in getResizedImage");
|
||||||
}
|
}
|
||||||
|
video::IImage* texture_image = getResizedImage(file, m_max_size,
|
||||||
|
&m_orig_size);
|
||||||
|
if (texture_image == NULL)
|
||||||
|
throw std::runtime_error("Missing texture_image in getResizedImage");
|
||||||
|
file->drop();
|
||||||
|
|
||||||
m_size = texture_image->getDimension();
|
m_size = texture_image->getDimension();
|
||||||
|
m_size_lock.unlock();
|
||||||
|
|
||||||
if (m_image_mani)
|
if (m_image_mani)
|
||||||
m_image_mani(texture_image);
|
m_image_mani(texture_image);
|
||||||
@ -364,6 +384,8 @@ void GEVulkanTexture::reloadInternal()
|
|||||||
uint8_t* data = (uint8_t*)texture_image->lock();
|
uint8_t* data = (uint8_t*)texture_image->lock();
|
||||||
bgraConversion(data);
|
bgraConversion(data);
|
||||||
upload(data);
|
upload(data);
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
|
||||||
texture_image->unlock();
|
texture_image->unlock();
|
||||||
texture_image->drop();
|
texture_image->drop();
|
||||||
} // reloadInternal
|
} // reloadInternal
|
||||||
@ -404,6 +426,9 @@ void* GEVulkanTexture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level)
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
uint8_t* GEVulkanTexture::getTextureData()
|
uint8_t* GEVulkanTexture::getTextureData()
|
||||||
{
|
{
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
|
||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
VkDeviceMemory buffer_memory;
|
VkDeviceMemory buffer_memory;
|
||||||
VkDeviceSize image_size =
|
VkDeviceSize image_size =
|
||||||
@ -462,6 +487,9 @@ cleanup:
|
|||||||
void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format,
|
void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format,
|
||||||
u32 w, u32 h, u32 x, u32 y)
|
u32 w, u32 h, u32 x, u32 y)
|
||||||
{
|
{
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
|
||||||
VkBuffer staging_buffer;
|
VkBuffer staging_buffer;
|
||||||
VkDeviceMemory staging_buffer_memory;
|
VkDeviceMemory staging_buffer_memory;
|
||||||
if (m_single_channel)
|
if (m_single_channel)
|
||||||
@ -555,4 +583,20 @@ void GEVulkanTexture::bgraConversion(uint8_t* img_data)
|
|||||||
}
|
}
|
||||||
} // bgraConversion
|
} // bgraConversion
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void GEVulkanTexture::reload()
|
||||||
|
{
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(m_vulkan_device);
|
||||||
|
if (!m_disable_reload)
|
||||||
|
{
|
||||||
|
m_size_lock.lock();
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
GEVulkanCommandLoader::addMultiThreadingCommand(
|
||||||
|
std::bind(&GEVulkanTexture::reloadInternal, this));
|
||||||
|
}
|
||||||
|
} // reload
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "vulkan_wrapper.h"
|
#include "vulkan_wrapper.h"
|
||||||
|
|
||||||
|
#include "ge_spin_lock.hpp"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ITexture.h>
|
#include <ITexture.h>
|
||||||
@ -34,6 +36,12 @@ private:
|
|||||||
|
|
||||||
const bool m_single_channel;
|
const bool m_single_channel;
|
||||||
|
|
||||||
|
GESpinLock m_size_lock;
|
||||||
|
|
||||||
|
GESpinLock m_image_view_lock;
|
||||||
|
|
||||||
|
io::path m_full_path;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool createTextureImage(uint8_t* texture_data);
|
bool createTextureImage(uint8_t* texture_data);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -83,9 +91,18 @@ public:
|
|||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual const core::dimension2d<u32>& getOriginalSize() const
|
virtual const core::dimension2d<u32>& getOriginalSize() const
|
||||||
{ return m_orig_size; }
|
{
|
||||||
|
m_size_lock.lock();
|
||||||
|
m_size_lock.unlock();
|
||||||
|
return m_orig_size;
|
||||||
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual const core::dimension2d<u32>& getSize() const { return m_size; }
|
virtual const core::dimension2d<u32>& getSize() const
|
||||||
|
{
|
||||||
|
m_size_lock.lock();
|
||||||
|
m_size_lock.unlock();
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual video::E_DRIVER_TYPE getDriverType() const
|
virtual video::E_DRIVER_TYPE getDriverType() const
|
||||||
{ return video::EDT_VULKAN; }
|
{ return video::EDT_VULKAN; }
|
||||||
@ -99,16 +116,22 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void regenerateMipMapLevels(void* mipmap_data = NULL) {}
|
virtual void regenerateMipMapLevels(void* mipmap_data = NULL) {}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual u64 getTextureHandler() const { return (u64)m_image_view; }
|
virtual u64 getTextureHandler() const
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
virtual unsigned int getTextureSize() const { return m_texture_size; }
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
virtual void reload()
|
|
||||||
{
|
{
|
||||||
vkDeviceWaitIdle(m_vulkan_device);
|
m_image_view_lock.lock();
|
||||||
reloadInternal();
|
m_image_view_lock.unlock();
|
||||||
|
return (u64)m_image_view;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
virtual unsigned int getTextureSize() const
|
||||||
|
{
|
||||||
|
m_image_view_lock.lock();
|
||||||
|
m_image_view_lock.unlock();
|
||||||
|
return m_texture_size;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void reload();
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
virtual void updateTexture(void* data, irr::video::ECOLOR_FORMAT format,
|
virtual void updateTexture(void* data, irr::video::ECOLOR_FORMAT format,
|
||||||
u32 w, u32 h, u32 x, u32 y);
|
u32 w, u32 h, u32 x, u32 y);
|
||||||
}; // GEVulkanTexture
|
}; // GEVulkanTexture
|
||||||
|
Loading…
Reference in New Issue
Block a user