Use class inheritance for GEVulkanMeshCache

This commit is contained in:
Benau 2022-06-08 13:38:24 +08:00
parent b0cddc462a
commit d85c1e3ee7
10 changed files with 110 additions and 125 deletions

View File

@ -22,6 +22,7 @@ using namespace video;
namespace GE namespace GE
{ {
class GEVulkanMeshCache;
enum GEVulkanSampler : unsigned enum GEVulkanSampler : unsigned
{ {
GVS_MIN = 0, GVS_MIN = 0,
@ -473,6 +474,7 @@ namespace GE
std::string getDriverVersionString() const; std::string getDriverVersionString() const;
void destroySwapChainRelated(bool handle_surface); void destroySwapChainRelated(bool handle_surface);
void createSwapChainRelated(bool handle_surface); void createSwapChainRelated(bool handle_surface);
GEVulkanMeshCache* getVulkanMeshCache() const;
}; };
} }

View File

@ -1,27 +0,0 @@
#ifndef HEADER_GE_VULKAN_MESH_CACHE_HPP
#define HEADER_GE_VULKAN_MESH_CACHE_HPP
#include "vulkan_wrapper.h"
namespace GE
{
class GEVulkanDriver;
namespace GEVulkanMeshCache
{
// ----------------------------------------------------------------------------
void init(GEVulkanDriver*);
// ----------------------------------------------------------------------------
void irrlichtMeshChanged();
// ----------------------------------------------------------------------------
void updateCache();
// ----------------------------------------------------------------------------
void destroy();
// ----------------------------------------------------------------------------
VkBuffer getVBO();
// ----------------------------------------------------------------------------
VkBuffer getIBO();
}; // GEVulkanMeshCache
}
#endif

View File

@ -14,7 +14,6 @@ public:
GEVulkanSceneManager(irr::video::IVideoDriver* driver, GEVulkanSceneManager(irr::video::IVideoDriver* driver,
irr::io::IFileSystem* fs, irr::io::IFileSystem* fs,
irr::gui::ICursorControl* cursor_control, irr::gui::ICursorControl* cursor_control,
irr::scene::IMeshCache* cache,
irr::gui::IGUIEnvironment* gui_environment); irr::gui::IGUIEnvironment* gui_environment);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
~GEVulkanSceneManager(); ~GEVulkanSceneManager();

View File

@ -9,6 +9,9 @@
#include "ge_vulkan_texture.hpp" #include "ge_vulkan_texture.hpp"
#include "ge_vulkan_command_loader.hpp" #include "ge_vulkan_command_loader.hpp"
#include "ISceneManager.h"
#include "IrrlichtDevice.h"
#ifdef _IRR_COMPILE_WITH_VULKAN_ #ifdef _IRR_COMPILE_WITH_VULKAN_
#include "SDL_vulkan.h" #include "SDL_vulkan.h"
#include <algorithm> #include <algorithm>
@ -552,7 +555,6 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
// For GEVulkanDynamicBuffer // For GEVulkanDynamicBuffer
GE::setVideoDriver(this); GE::setVideoDriver(this);
GEVulkan2dRenderer::init(this); GEVulkan2dRenderer::init(this);
GEVulkanMeshCache::init(this);
createUnicolorTextures(); createUnicolorTextures();
GEVulkanFeatures::printStats(); GEVulkanFeatures::printStats();
} }
@ -583,7 +585,7 @@ void GEVulkanDriver::destroyVulkan()
m_transparent_texture = NULL; m_transparent_texture = NULL;
} }
GEVulkanMeshCache::destroy(); getVulkanMeshCache()->destroy();
GEVulkan2dRenderer::destroy(); GEVulkan2dRenderer::destroy();
GEVulkanShaderManager::destroy(); GEVulkanShaderManager::destroy();
@ -2026,6 +2028,13 @@ void GEVulkanDriver::waitIdle()
m->unlock(); m->unlock();
} // waitIdle } // waitIdle
// ----------------------------------------------------------------------------
GEVulkanMeshCache* GEVulkanDriver::getVulkanMeshCache() const
{
return static_cast<GEVulkanMeshCache*>
(m_irrlicht_device->getSceneManager()->getMeshCache());
} // getVulkanMeshCache
} }
namespace irr namespace irr

View File

@ -5,59 +5,45 @@
#include "ge_vulkan_driver.hpp" #include "ge_vulkan_driver.hpp"
#include "IAnimatedMesh.h" #include "IAnimatedMesh.h"
#include "IMeshCache.h"
#include "ISceneManager.h"
#include "IrrlichtDevice.h"
#include <vector> #include <vector>
namespace GE namespace GE
{ {
namespace GEVulkanMeshCache
{
// ============================================================================
GEVulkanDriver* g_vk;
uint64_t g_irrlicht_cache_time;
uint64_t g_ge_cache_time;
VkBuffer g_vbo_buffer;
VkDeviceMemory g_vbo_memory;
VkBuffer g_ibo_buffer;
VkDeviceMemory g_ibo_memory;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void init(GEVulkanDriver* vk) GEVulkanMeshCache::GEVulkanMeshCache()
: irr::scene::CMeshCache()
{ {
g_vk = vk; m_vk = getVKDriver();
g_irrlicht_cache_time = getMonoTimeMs(); m_irrlicht_cache_time = getMonoTimeMs();
g_ge_cache_time = 0; m_ge_cache_time = 0;
g_vbo_buffer = VK_NULL_HANDLE; m_vbo_buffer = VK_NULL_HANDLE;
g_vbo_memory = VK_NULL_HANDLE; m_vbo_memory = VK_NULL_HANDLE;
g_ibo_buffer = VK_NULL_HANDLE; m_ibo_buffer = VK_NULL_HANDLE;
g_ibo_memory = VK_NULL_HANDLE; m_ibo_memory = VK_NULL_HANDLE;
} // init } // init
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void irrlichtMeshChanged() void GEVulkanMeshCache::meshCacheChanged()
{ {
g_irrlicht_cache_time = getMonoTimeMs(); m_irrlicht_cache_time = getMonoTimeMs();
} // irrlichtMeshChanged } // meshCacheChanged
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void updateCache() void GEVulkanMeshCache::updateCache()
{ {
if (g_irrlicht_cache_time <= g_ge_cache_time) if (m_irrlicht_cache_time <= m_ge_cache_time)
return; return;
g_ge_cache_time = g_irrlicht_cache_time; m_ge_cache_time = m_irrlicht_cache_time;
destroy(); destroy();
size_t vbo_size, ibo_size; size_t vbo_size, ibo_size;
vbo_size = 0; vbo_size = 0;
ibo_size = 0; ibo_size = 0;
scene::IMeshCache* cache = g_vk->getIrrlichtDevice()->getSceneManager()
->getMeshCache();
std::vector<GESPMBuffer*> buffers; std::vector<GESPMBuffer*> buffers;
for (unsigned i = 0; i < cache->getMeshCount(); i++) for (unsigned i = 0; i < Meshes.size(); i++)
{ {
scene::IAnimatedMesh* mesh = cache->getMeshByIndex(i); scene::IAnimatedMesh* mesh = Meshes[i].Mesh;
if (mesh->getMeshType() != scene::EAMT_SPM) if (mesh->getMeshType() != scene::EAMT_SPM)
continue; continue;
for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++) for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++)
@ -74,7 +60,7 @@ void updateCache()
VkBuffer staging_buffer = VK_NULL_HANDLE; VkBuffer staging_buffer = VK_NULL_HANDLE;
VkDeviceMemory staging_memory = VK_NULL_HANDLE; VkDeviceMemory staging_memory = VK_NULL_HANDLE;
if (!g_vk->createBuffer(vbo_size, if (!m_vk->createBuffer(vbo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
@ -82,7 +68,7 @@ void updateCache()
throw std::runtime_error("updateCache create staging vbo failed"); throw std::runtime_error("updateCache create staging vbo failed");
uint8_t* mapped; uint8_t* mapped;
if (vkMapMemory(g_vk->getDevice(), staging_memory, 0, if (vkMapMemory(m_vk->getDevice(), staging_memory, 0,
vbo_size, 0, (void**)&mapped) != VK_SUCCESS) vbo_size, 0, (void**)&mapped) != VK_SUCCESS)
throw std::runtime_error("updateCache vkMapMemory failed"); throw std::runtime_error("updateCache vkMapMemory failed");
size_t offset = 0; size_t offset = 0;
@ -96,25 +82,25 @@ void updateCache()
offset += copy_size; offset += copy_size;
} }
if (!g_vk->createBuffer(vbo_size, if (!m_vk->createBuffer(vbo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
g_vbo_buffer, g_vbo_memory)) m_vbo_buffer, m_vbo_memory))
throw std::runtime_error("updateCache create vbo failed"); throw std::runtime_error("updateCache create vbo failed");
g_vk->copyBuffer(staging_buffer, g_vbo_buffer, vbo_size); m_vk->copyBuffer(staging_buffer, m_vbo_buffer, vbo_size);
vkUnmapMemory(g_vk->getDevice(), staging_memory); vkUnmapMemory(m_vk->getDevice(), staging_memory);
vkFreeMemory(g_vk->getDevice(), staging_memory, NULL); vkFreeMemory(m_vk->getDevice(), staging_memory, NULL);
vkDestroyBuffer(g_vk->getDevice(), staging_buffer, NULL); vkDestroyBuffer(m_vk->getDevice(), staging_buffer, NULL);
if (!g_vk->createBuffer(ibo_size, if (!m_vk->createBuffer(ibo_size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging_buffer, staging_memory)) staging_buffer, staging_memory))
throw std::runtime_error("updateCache create staging ibo failed"); throw std::runtime_error("updateCache create staging ibo failed");
if (vkMapMemory(g_vk->getDevice(), staging_memory, 0, if (vkMapMemory(m_vk->getDevice(), staging_memory, 0,
ibo_size, 0, (void**)&mapped) != VK_SUCCESS) ibo_size, 0, (void**)&mapped) != VK_SUCCESS)
throw std::runtime_error("updateCache vkMapMemory failed"); throw std::runtime_error("updateCache vkMapMemory failed");
offset = 0; offset = 0;
@ -126,50 +112,36 @@ void updateCache()
offset += copy_size; offset += copy_size;
} }
if (!g_vk->createBuffer(ibo_size, if (!m_vk->createBuffer(ibo_size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
g_ibo_buffer, g_ibo_memory)) m_ibo_buffer, m_ibo_memory))
throw std::runtime_error("updateCache create ibo failed"); throw std::runtime_error("updateCache create ibo failed");
g_vk->copyBuffer(staging_buffer, g_ibo_buffer, ibo_size); m_vk->copyBuffer(staging_buffer, m_ibo_buffer, ibo_size);
vkUnmapMemory(g_vk->getDevice(), staging_memory); vkUnmapMemory(m_vk->getDevice(), staging_memory);
vkFreeMemory(g_vk->getDevice(), staging_memory, NULL); vkFreeMemory(m_vk->getDevice(), staging_memory, NULL);
vkDestroyBuffer(g_vk->getDevice(), staging_buffer, NULL); vkDestroyBuffer(m_vk->getDevice(), staging_buffer, NULL);
} // updateCache } // updateCache
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void destroy() void GEVulkanMeshCache::destroy()
{ {
g_vk->waitIdle(); m_vk->waitIdle();
if (g_vbo_memory != VK_NULL_HANDLE) if (m_vbo_memory != VK_NULL_HANDLE)
vkFreeMemory(g_vk->getDevice(), g_vbo_memory, NULL); vkFreeMemory(m_vk->getDevice(), m_vbo_memory, NULL);
g_vbo_memory = VK_NULL_HANDLE; m_vbo_memory = VK_NULL_HANDLE;
if (g_vbo_buffer != VK_NULL_HANDLE) if (m_vbo_buffer != VK_NULL_HANDLE)
vkDestroyBuffer(g_vk->getDevice(), g_vbo_buffer, NULL); vkDestroyBuffer(m_vk->getDevice(), m_vbo_buffer, NULL);
g_vbo_buffer = VK_NULL_HANDLE; m_vbo_buffer = VK_NULL_HANDLE;
if (g_ibo_memory != VK_NULL_HANDLE) if (m_ibo_memory != VK_NULL_HANDLE)
vkFreeMemory(g_vk->getDevice(), g_ibo_memory, NULL); vkFreeMemory(m_vk->getDevice(), m_ibo_memory, NULL);
g_ibo_memory = VK_NULL_HANDLE; m_ibo_memory = VK_NULL_HANDLE;
if (g_ibo_buffer != VK_NULL_HANDLE) if (m_ibo_buffer != VK_NULL_HANDLE)
vkDestroyBuffer(g_vk->getDevice(), g_ibo_buffer, NULL); vkDestroyBuffer(m_vk->getDevice(), m_ibo_buffer, NULL);
g_ibo_buffer = VK_NULL_HANDLE; m_ibo_buffer = VK_NULL_HANDLE;
} // destroy } // destroy
// ----------------------------------------------------------------------------
VkBuffer getVBO()
{
return g_vbo_buffer;
} // getVBO
// ----------------------------------------------------------------------------
VkBuffer getIBO()
{
return g_ibo_buffer;
} // getIBO
}
} }

View File

@ -0,0 +1,39 @@
#ifndef HEADER_GE_VULKAN_MESH_CACHE_HPP
#define HEADER_GE_VULKAN_MESH_CACHE_HPP
#include "vulkan_wrapper.h"
#include "../source/Irrlicht/CMeshCache.h"
#include <cstdint>
namespace GE
{
class GEVulkanDriver;
class GEVulkanMeshCache : public irr::scene::CMeshCache
{
private:
GEVulkanDriver* m_vk;
uint64_t m_irrlicht_cache_time, m_ge_cache_time;
VkBuffer m_vbo_buffer, m_ibo_buffer;
VkDeviceMemory m_vbo_memory, m_ibo_memory;
public:
// ------------------------------------------------------------------------
GEVulkanMeshCache();
// ------------------------------------------------------------------------
virtual void meshCacheChanged();
// ------------------------------------------------------------------------
void updateCache();
// ------------------------------------------------------------------------
void destroy();
// ------------------------------------------------------------------------
VkBuffer getVBO() const { return m_vbo_buffer; }
// ------------------------------------------------------------------------
VkBuffer getIBO() const { return m_ibo_buffer; }
}; // GEVulkanMeshCache
}
#endif

View File

@ -1,15 +1,16 @@
#include "ge_vulkan_scene_manager.hpp" #include "ge_vulkan_scene_manager.hpp"
#include "ge_vulkan_mesh_cache.hpp"
namespace GE namespace GE
{ {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
GEVulkanSceneManager::GEVulkanSceneManager(irr::video::IVideoDriver* driver, GEVulkanSceneManager::GEVulkanSceneManager(irr::video::IVideoDriver* driver,
irr::io::IFileSystem* fs, irr::io::IFileSystem* fs,
irr::gui::ICursorControl* cursor_control, irr::gui::ICursorControl* cursor_control,
irr::scene::IMeshCache* cache,
irr::gui::IGUIEnvironment* gui_environment) irr::gui::IGUIEnvironment* gui_environment)
: CSceneManager(driver, fs, cursor_control, cache, : CSceneManager(driver, fs, cursor_control,
gui_environment) new GEVulkanMeshCache(), gui_environment)
{ {
} // GEVulkanSceneManager } // GEVulkanSceneManager

View File

@ -1596,7 +1596,7 @@ void CIrrDeviceSDL::createGUIAndVulkanScene()
#endif #endif
// create Scene manager // create Scene manager
SceneManager = new GE::GEVulkanSceneManager(VideoDriver, FileSystem, CursorControl, NULL, GUIEnvironment); SceneManager = new GE::GEVulkanSceneManager(VideoDriver, FileSystem, CursorControl, GUIEnvironment);
setEventReceiver(UserReceiver); setEventReceiver(UserReceiver);
} }

View File

@ -6,10 +6,6 @@
#include "IAnimatedMesh.h" #include "IAnimatedMesh.h"
#include "IMesh.h" #include "IMesh.h"
#ifndef SERVER_ONLY
#include <ge_vulkan_mesh_cache.hpp>
#endif
namespace irr namespace irr
{ {
namespace scene namespace scene
@ -33,9 +29,7 @@ void CMeshCache::addMesh(const io::path& filename, IAnimatedMesh* mesh)
e.Mesh = mesh; e.Mesh = mesh;
Meshes.push_back(e); Meshes.push_back(e);
#ifndef SERVER_ONLY meshCacheChanged();
GE::GEVulkanMeshCache::irrlichtMeshChanged();
#endif
} }
@ -50,9 +44,7 @@ void CMeshCache::removeMesh(const IMesh* const mesh)
{ {
Meshes[i].Mesh->drop(); Meshes[i].Mesh->drop();
Meshes.erase(i); Meshes.erase(i);
#ifndef SERVER_ONLY meshCacheChanged();
GE::GEVulkanMeshCache::irrlichtMeshChanged();
#endif
return; return;
} }
} }
@ -166,9 +158,7 @@ void CMeshCache::clear()
Meshes[i].Mesh->drop(); Meshes[i].Mesh->drop();
Meshes.clear(); Meshes.clear();
#ifndef SERVER_ONLY meshCacheChanged();
GE::GEVulkanMeshCache::irrlichtMeshChanged();
#endif
} }
//! Clears all meshes that are held in the mesh cache but not used anywhere else. //! Clears all meshes that are held in the mesh cache but not used anywhere else.
@ -181,9 +171,7 @@ void CMeshCache::clearUnusedMeshes()
Meshes[i].Mesh->drop(); Meshes[i].Mesh->drop();
Meshes.erase(i); Meshes.erase(i);
--i; --i;
#ifndef SERVER_ONLY meshCacheChanged();
GE::GEVulkanMeshCache::irrlichtMeshChanged();
#endif
} }
} }
} }

View File

@ -113,6 +113,8 @@ namespace scene
//! loaded meshes //! loaded meshes
core::array<MeshEntry> Meshes; core::array<MeshEntry> Meshes;
virtual void meshCacheChanged() {}
}; };