Add GEVulkanMeshCache
This commit is contained in:
parent
95d9277046
commit
ca1f61b898
@ -31,6 +31,7 @@ set(GE_SOURCES
|
||||
src/ge_vulkan_driver.cpp
|
||||
src/ge_vulkan_dynamic_buffer.cpp
|
||||
src/ge_vulkan_features.cpp
|
||||
src/ge_vulkan_mesh_cache.cpp
|
||||
src/ge_vulkan_shader_manager.cpp
|
||||
src/ge_vulkan_texture.cpp
|
||||
src/ge_gl_texture.cpp
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef HEADER_GE_SPM_BUFFER_HPP
|
||||
#define HEADER_GE_SPM_BUFFER_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include "IMeshBuffer.h"
|
||||
|
||||
@ -21,7 +22,17 @@ private:
|
||||
std::vector<irr::u16> m_indices;
|
||||
|
||||
irr::core::aabbox3d<irr::f32> m_bounding_box;
|
||||
|
||||
size_t m_vbo_offset;
|
||||
|
||||
size_t m_ibo_offset;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GESPMBuffer()
|
||||
{
|
||||
m_vbo_offset = 0;
|
||||
m_ibo_offset = 0;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const irr::video::SMaterial& getMaterial() const
|
||||
{ return m_material; }
|
||||
@ -33,7 +44,6 @@ public:
|
||||
{ return m_vertices.data(); }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void* getVertices() { return m_vertices.data(); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
virtual irr::u32 getVertexCount() const { return m_vertices.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -139,7 +149,14 @@ public:
|
||||
virtual irr::u32 getChangedID_Vertex() const { return 0; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual irr::u32 getChangedID_Index() const { return 0; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setVBOOffset(size_t offset) { m_vbo_offset = offset; }
|
||||
// ------------------------------------------------------------------------
|
||||
size_t getVBOOffset() const { return m_vbo_offset; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setIBOOffset(size_t offset) { m_ibo_offset = offset; }
|
||||
// ------------------------------------------------------------------------
|
||||
size_t getIBOOffset() const { return m_ibo_offset; }
|
||||
};
|
||||
|
||||
} // end namespace irr
|
||||
|
27
lib/graphics_engine/include/ge_vulkan_mesh_cache.hpp
Normal file
27
lib/graphics_engine/include/ge_vulkan_mesh_cache.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#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
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "ge_vulkan_2d_renderer.hpp"
|
||||
#include "ge_vulkan_features.hpp"
|
||||
#include "ge_vulkan_mesh_cache.hpp"
|
||||
#include "ge_vulkan_shader_manager.hpp"
|
||||
#include "ge_vulkan_texture.hpp"
|
||||
#include "ge_vulkan_command_loader.hpp"
|
||||
@ -551,6 +552,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
// For GEVulkanDynamicBuffer
|
||||
GE::setVideoDriver(this);
|
||||
GEVulkan2dRenderer::init(this);
|
||||
GEVulkanMeshCache::init(this);
|
||||
createUnicolorTextures();
|
||||
GEVulkanFeatures::printStats();
|
||||
}
|
||||
@ -581,6 +583,7 @@ void GEVulkanDriver::destroyVulkan()
|
||||
m_transparent_texture = NULL;
|
||||
}
|
||||
|
||||
GEVulkanMeshCache::destroy();
|
||||
GEVulkan2dRenderer::destroy();
|
||||
GEVulkanShaderManager::destroy();
|
||||
|
||||
|
175
lib/graphics_engine/src/ge_vulkan_mesh_cache.cpp
Normal file
175
lib/graphics_engine/src/ge_vulkan_mesh_cache.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include "ge_vulkan_mesh_cache.hpp"
|
||||
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_spm_buffer.hpp"
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
|
||||
#include "IAnimatedMesh.h"
|
||||
#include "IMeshCache.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "IrrlichtDevice.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
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)
|
||||
{
|
||||
g_vk = vk;
|
||||
g_irrlicht_cache_time = getMonoTimeMs();
|
||||
g_ge_cache_time = 0;
|
||||
g_vbo_buffer = VK_NULL_HANDLE;
|
||||
g_vbo_memory = VK_NULL_HANDLE;
|
||||
g_ibo_buffer = VK_NULL_HANDLE;
|
||||
g_ibo_memory = VK_NULL_HANDLE;
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void irrlichtMeshChanged()
|
||||
{
|
||||
g_irrlicht_cache_time = getMonoTimeMs();
|
||||
} // irrlichtMeshChanged
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void updateCache()
|
||||
{
|
||||
if (g_irrlicht_cache_time <= g_ge_cache_time)
|
||||
return;
|
||||
g_ge_cache_time = g_irrlicht_cache_time;
|
||||
|
||||
destroy();
|
||||
size_t vbo_size, ibo_size;
|
||||
vbo_size = 0;
|
||||
ibo_size = 0;
|
||||
scene::IMeshCache* cache = g_vk->getIrrlichtDevice()->getSceneManager()
|
||||
->getMeshCache();
|
||||
std::vector<GESPMBuffer*> buffers;
|
||||
for (unsigned i = 0; i < cache->getMeshCount(); i++)
|
||||
{
|
||||
scene::IAnimatedMesh* mesh = cache->getMeshByIndex(i);
|
||||
if (mesh->getMeshType() != scene::EAMT_SPM)
|
||||
continue;
|
||||
for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++)
|
||||
{
|
||||
scene::IMeshBuffer* mb = mesh->getMeshBuffer(j);
|
||||
vbo_size += mesh->getMeshBuffer(j)->getVertexCount();
|
||||
ibo_size += mesh->getMeshBuffer(j)->getIndexCount();
|
||||
buffers.push_back(static_cast<GESPMBuffer*>(mb));
|
||||
}
|
||||
}
|
||||
vbo_size *= getVertexPitchFromType(video::EVT_SKINNED_MESH);
|
||||
ibo_size *= sizeof(uint16_t);
|
||||
|
||||
VkBuffer staging_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory staging_memory = VK_NULL_HANDLE;
|
||||
|
||||
if (!g_vk->createBuffer(vbo_size,
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
staging_buffer, staging_memory))
|
||||
throw std::runtime_error("updateCache create staging vbo failed");
|
||||
|
||||
uint8_t* mapped;
|
||||
if (vkMapMemory(g_vk->getDevice(), staging_memory, 0,
|
||||
vbo_size, 0, (void**)&mapped) != VK_SUCCESS)
|
||||
throw std::runtime_error("updateCache vkMapMemory failed");
|
||||
size_t offset = 0;
|
||||
for (GESPMBuffer* spm_buffer : buffers)
|
||||
{
|
||||
size_t copy_size = spm_buffer->getVertexCount() *
|
||||
getVertexPitchFromType(video::EVT_SKINNED_MESH);
|
||||
memcpy(&mapped[offset], spm_buffer->getVertices(), copy_size);
|
||||
spm_buffer->setVBOOffset(
|
||||
offset / getVertexPitchFromType(video::EVT_SKINNED_MESH));
|
||||
offset += copy_size;
|
||||
}
|
||||
|
||||
if (!g_vk->createBuffer(vbo_size,
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
g_vbo_buffer, g_vbo_memory))
|
||||
throw std::runtime_error("updateCache create vbo failed");
|
||||
|
||||
g_vk->copyBuffer(staging_buffer, g_vbo_buffer, vbo_size);
|
||||
vkUnmapMemory(g_vk->getDevice(), staging_memory);
|
||||
vkFreeMemory(g_vk->getDevice(), staging_memory, NULL);
|
||||
vkDestroyBuffer(g_vk->getDevice(), staging_buffer, NULL);
|
||||
|
||||
if (!g_vk->createBuffer(ibo_size,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
staging_buffer, staging_memory))
|
||||
throw std::runtime_error("updateCache create staging ibo failed");
|
||||
|
||||
if (vkMapMemory(g_vk->getDevice(), staging_memory, 0,
|
||||
ibo_size, 0, (void**)&mapped) != VK_SUCCESS)
|
||||
throw std::runtime_error("updateCache vkMapMemory failed");
|
||||
offset = 0;
|
||||
for (GESPMBuffer* spm_buffer : buffers)
|
||||
{
|
||||
size_t copy_size = spm_buffer->getIndexCount() * sizeof(uint16_t);
|
||||
memcpy(&mapped[offset], spm_buffer->getIndices(), copy_size);
|
||||
spm_buffer->setIBOOffset(offset / sizeof(uint16_t));
|
||||
offset += copy_size;
|
||||
}
|
||||
|
||||
if (!g_vk->createBuffer(ibo_size,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
g_ibo_buffer, g_ibo_memory))
|
||||
throw std::runtime_error("updateCache create ibo failed");
|
||||
|
||||
g_vk->copyBuffer(staging_buffer, g_ibo_buffer, ibo_size);
|
||||
vkUnmapMemory(g_vk->getDevice(), staging_memory);
|
||||
vkFreeMemory(g_vk->getDevice(), staging_memory, NULL);
|
||||
vkDestroyBuffer(g_vk->getDevice(), staging_buffer, NULL);
|
||||
} // updateCache
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void destroy()
|
||||
{
|
||||
g_vk->waitIdle();
|
||||
|
||||
if (g_vbo_memory != VK_NULL_HANDLE)
|
||||
vkFreeMemory(g_vk->getDevice(), g_vbo_memory, NULL);
|
||||
g_vbo_memory = VK_NULL_HANDLE;
|
||||
if (g_vbo_buffer != VK_NULL_HANDLE)
|
||||
vkDestroyBuffer(g_vk->getDevice(), g_vbo_buffer, NULL);
|
||||
g_vbo_buffer = VK_NULL_HANDLE;
|
||||
|
||||
if (g_ibo_memory != VK_NULL_HANDLE)
|
||||
vkFreeMemory(g_vk->getDevice(), g_ibo_memory, NULL);
|
||||
g_ibo_memory = VK_NULL_HANDLE;
|
||||
if (g_ibo_buffer != VK_NULL_HANDLE)
|
||||
vkDestroyBuffer(g_vk->getDevice(), g_ibo_buffer, NULL);
|
||||
g_ibo_buffer = VK_NULL_HANDLE;
|
||||
} // destroy
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
VkBuffer getVBO()
|
||||
{
|
||||
return g_vbo_buffer;
|
||||
} // getVBO
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
VkBuffer getIBO()
|
||||
{
|
||||
return g_ibo_buffer;
|
||||
} // getIBO
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,10 @@
|
||||
#include "IAnimatedMesh.h"
|
||||
#include "IMesh.h"
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ge_vulkan_mesh_cache.hpp>
|
||||
#endif
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
@ -29,6 +33,9 @@ void CMeshCache::addMesh(const io::path& filename, IAnimatedMesh* mesh)
|
||||
e.Mesh = mesh;
|
||||
|
||||
Meshes.push_back(e);
|
||||
#ifndef SERVER_ONLY
|
||||
GE::GEVulkanMeshCache::irrlichtMeshChanged();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -43,6 +50,9 @@ void CMeshCache::removeMesh(const IMesh* const mesh)
|
||||
{
|
||||
Meshes[i].Mesh->drop();
|
||||
Meshes.erase(i);
|
||||
#ifndef SERVER_ONLY
|
||||
GE::GEVulkanMeshCache::irrlichtMeshChanged();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -156,6 +166,9 @@ void CMeshCache::clear()
|
||||
Meshes[i].Mesh->drop();
|
||||
|
||||
Meshes.clear();
|
||||
#ifndef SERVER_ONLY
|
||||
GE::GEVulkanMeshCache::irrlichtMeshChanged();
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Clears all meshes that are held in the mesh cache but not used anywhere else.
|
||||
@ -168,6 +181,9 @@ void CMeshCache::clearUnusedMeshes()
|
||||
Meshes[i].Mesh->drop();
|
||||
Meshes.erase(i);
|
||||
--i;
|
||||
#ifndef SERVER_ONLY
|
||||
GE::GEVulkanMeshCache::irrlichtMeshChanged();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user