summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VertexLoaderManager.cpp
diff options
context:
space:
mode:
authorcomex <comexk@gmail.com>2014-08-24 23:53:28 -0400
committercomex <comexk@gmail.com>2014-09-28 21:23:28 -0400
commit63c62b277d6850279bd2a982535d5abde824e6e2 (patch)
treedef4ef41a504dd09c16f02cea82407b4f5d0edfc /Source/Core/VideoCommon/VertexLoaderManager.cpp
parent431fb4d82a9fa9597df3c35c27e55714ff3e27c0 (diff)
Some changes to VertexLoaderManager:
- Lazily create the native vertex format (which involves GL calls) from RunVertices rather than RefreshLoader itself, freeing the latter to be run from the CPU thread (hopefully). - In order to avoid useless allocations while doing so, store the native format inside the VertexLoader rather than using a cache entry. - Wrap the s_vertex_loader_map in a lock, for similar reasons.
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderManager.cpp')
-rw-r--r--Source/Core/VideoCommon/VertexLoaderManager.cpp88
1 files changed, 36 insertions, 52 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp
index dbf22c9c3d..b3a1c97c3f 100644
--- a/Source/Core/VideoCommon/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp
@@ -4,6 +4,7 @@
#include <algorithm>
#include <memory>
+#include <mutex>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -24,8 +25,7 @@ static int s_attr_dirty; // bitfield
static NativeVertexFormat* s_current_vtx_fmt;
-typedef std::pair<VertexLoader*, NativeVertexFormat*> VertexLoaderCacheItem;
-static VertexLoaderCacheItem s_VertexLoaders[8];
+static VertexLoader* s_VertexLoaders[8];
namespace std
{
@@ -41,14 +41,13 @@ struct hash<VertexLoaderUID>
}
-typedef std::unordered_map<VertexLoaderUID, VertexLoaderCacheItem> VertexLoaderMap;
-typedef std::map<PortableVertexDeclaration, std::unique_ptr<NativeVertexFormat>> NativeVertexLoaderMap;
+typedef std::unordered_map<VertexLoaderUID, std::unique_ptr<VertexLoader>> VertexLoaderMap;
namespace VertexLoaderManager
{
-static VertexLoaderMap s_VertexLoaderMap;
-static NativeVertexLoaderMap s_native_vertex_map;
+static std::mutex s_vertex_loader_map_lock;
+static VertexLoaderMap s_vertex_loader_map;
// TODO - change into array of pointers. Keep a map of all seen so far.
void Init()
@@ -56,20 +55,16 @@ void Init()
MarkAllDirty();
for (auto& map_entry : s_VertexLoaders)
{
- map_entry.first = nullptr;
- map_entry.second = nullptr;
+ map_entry = nullptr;
}
RecomputeCachedArraybases();
}
void Shutdown()
{
- for (auto& map_entry : s_VertexLoaderMap)
- {
- delete map_entry.second.first;
- }
- s_VertexLoaderMap.clear();
- s_native_vertex_map.clear();
+ std::lock_guard<std::mutex> lk(s_vertex_loader_map_lock);
+ s_vertex_loader_map.clear();
+ VertexLoader::ClearNativeVertexFormatCache();
}
namespace
@@ -87,14 +82,15 @@ struct entry
void AppendListToString(std::string *dest)
{
+ std::lock_guard<std::mutex> lk(s_vertex_loader_map_lock);
std::vector<entry> entries;
size_t total_size = 0;
- for (const auto& map_entry : s_VertexLoaderMap)
+ for (const auto& map_entry : s_vertex_loader_map)
{
entry e;
- map_entry.second.first->AppendToString(&e.text);
- e.num_verts = map_entry.second.first->GetNumLoadedVerts();
+ map_entry.second->AppendToString(&e.text);
+ e.num_verts = map_entry.second->GetNumLoadedVerts();
entries.push_back(e);
total_size += e.text.size() + 1;
}
@@ -111,54 +107,39 @@ void MarkAllDirty()
s_attr_dirty = 0xff;
}
-static NativeVertexFormat* GetNativeVertexFormat(const PortableVertexDeclaration& format,
- u32 components)
-{
- auto& native = s_native_vertex_map[format];
- if (!native)
- {
- auto raw_pointer = g_vertex_manager->CreateNativeVertexFormat();
- native = std::unique_ptr<NativeVertexFormat>(raw_pointer);
- native->Initialize(format);
- native->m_components = components;
- }
- return native.get();
-}
-
-static VertexLoaderCacheItem RefreshLoader(int vtx_attr_group)
+static VertexLoader* RefreshLoader(int vtx_attr_group)
{
+ VertexLoader* loader;
if ((s_attr_dirty >> vtx_attr_group) & 1)
{
VertexLoaderUID uid(g_VtxDesc, g_VtxAttr[vtx_attr_group]);
- VertexLoaderMap::iterator iter = s_VertexLoaderMap.find(uid);
- if (iter != s_VertexLoaderMap.end())
+ std::lock_guard<std::mutex> lk(s_vertex_loader_map_lock);
+ VertexLoaderMap::iterator iter = s_vertex_loader_map.find(uid);
+ if (iter != s_vertex_loader_map.end())
{
- s_VertexLoaders[vtx_attr_group] = iter->second;
+ loader = iter->second.get();
}
else
{
- VertexLoader* loader = new VertexLoader(g_VtxDesc, g_VtxAttr[vtx_attr_group]);
-
- NativeVertexFormat* vtx_fmt = GetNativeVertexFormat(
- loader->GetNativeVertexDeclaration(),
- loader->GetNativeComponents());
-
- s_VertexLoaderMap[uid] = std::make_pair(loader, vtx_fmt);
- s_VertexLoaders[vtx_attr_group] = std::make_pair(loader, vtx_fmt);
+ loader = new VertexLoader(g_VtxDesc, g_VtxAttr[vtx_attr_group]);
+ s_vertex_loader_map[uid] = std::unique_ptr<VertexLoader>(loader);
INCSTAT(stats.numVertexLoaders);
}
+ s_VertexLoaders[vtx_attr_group] = loader;
+ s_attr_dirty &= ~(1 << vtx_attr_group);
+ } else {
+ loader = s_VertexLoaders[vtx_attr_group];
}
- s_attr_dirty &= ~(1 << vtx_attr_group);
- return s_VertexLoaders[vtx_attr_group];
+ return loader;
}
bool RunVertices(int vtx_attr_group, int primitive, int count, size_t buf_size, bool skip_drawing)
{
if (!count)
return true;
- auto loader = RefreshLoader(vtx_attr_group);
+ VertexLoader* loader = RefreshLoader(vtx_attr_group);
- size_t size = count * loader.first->GetVertexSize();
+ size_t size = count * loader->GetVertexSize();
if (buf_size < size)
return false;
@@ -169,15 +150,18 @@ bool RunVertices(int vtx_attr_group, int primitive, int count, size_t buf_size,
return true;
}
+ NativeVertexFormat* native = loader->GetNativeVertexFormat();
+
+
// If the native vertex format changed, force a flush.
- if (loader.second != s_current_vtx_fmt)
+ if (native != s_current_vtx_fmt)
VertexManager::Flush();
- s_current_vtx_fmt = loader.second;
+ s_current_vtx_fmt = native;
VertexManager::PrepareForAdditionalData(primitive, count,
- loader.first->GetNativeVertexDeclaration().stride);
+ loader->GetNativeVertexDeclaration().stride);
- loader.first->RunVertices(g_VtxAttr[vtx_attr_group], primitive, count);
+ loader->RunVertices(g_VtxAttr[vtx_attr_group], primitive, count);
IndexGenerator::AddIndices(primitive, count);
@@ -188,7 +172,7 @@ bool RunVertices(int vtx_attr_group, int primitive, int count, size_t buf_size,
int GetVertexSize(int vtx_attr_group)
{
- return RefreshLoader(vtx_attr_group).first->GetVertexSize();
+ return RefreshLoader(vtx_attr_group)->GetVertexSize();
}
NativeVertexFormat* GetCurrentVertexFormat()