Eliminated a memcpy in DX11's vertex shader disk cache loading. Maybe games will boot faster now, who knows?

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7422 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak 2011-03-30 10:46:27 +00:00
parent 3d5d205c73
commit 306c3570d1
5 changed files with 59 additions and 45 deletions

View File

@ -20,6 +20,7 @@
#include "Common.h"
#include <fstream>
#include <functional>
// Update this to the current SVN revision every time you change shader generation code.
// We don't automatically get this from SVN_REV because that would mean regenerating the
@ -43,12 +44,15 @@ enum
// value_type[value_size] value;
//}
template <typename K, typename V>
class LinearDiskCacheReader
{
public:
virtual void Read(const K &key, const V *value, u32 value_size) = 0;
};
// Example reader:
//
//class LinearDiskCacheReader
//{
//public:
// template <typename F>
// void operator()(const K& key, u32 value_size, F get_data) const
// {...}
//};
// Dead simple unsorted key-value store with append functionality.
// No random read functionality, all reading is done in OpenAndRead.
@ -67,48 +71,45 @@ class LinearDiskCache
{
public:
// return number of read entries
u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader)
template <typename LinearDiskCacheReader>
u32 OpenAndRead(const char* filename, LinearDiskCacheReader& reader)
{
using std::ios_base;
using std::ios;
// close any currently opened file
Close();
// try opening for reading/writing
m_file.open(filename, ios_base::in | ios_base::out | ios_base::binary | ios_base::app);
m_file.open(filename, ios::in | ios::out | ios::binary | ios::app);
if (m_file.is_open() && ValidateHeader())
{
// good header, read some key/value pairs
u32 num_entries = 0;
K key;
V *value = NULL;
u32 value_size;
while (Read(&value_size))
K key;
while (Read(&value_size) && Read(&key))
{
delete[] value;
value = new V[value_size];
std::streamoff const pos = m_file.tellg();
// read key/value and pass to reader
if (Read(&key) && Read(value, value_size))
reader.Read(key, value, value_size);
else
break;
// pass key and value_size to reader with callback function to read the data
reader(key, value_size, [this, &value_size](V* data){ Read(data, value_size); });
// seek past data (in case reader didn't read it for whatever reason)
m_file.seekg(pos + (value_size * sizeof(V)), ios::beg);
++num_entries;
}
m_file.clear();
delete[] value;
return num_entries;
}
// failed to open file for reading or bad header
// close and recreate file
Close();
m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary);
m_file.open(filename, ios::out | ios::trunc | ios::binary);
WriteHeader();
return 0;
}

View File

@ -306,12 +306,16 @@ ID3D11Buffer*const& PixelShaderCache::GetConstantBuffer()
}
// this class will load the precompiled shaders into our cache
class PixelShaderCacheInserter : public LinearDiskCacheReader<PIXELSHADERUID, u8>
class PixelShaderCacheInserter
{
public:
void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size)
template <typename F>
void operator()(const PIXELSHADERUID& key, u32 value_size, F get_data) const
{
PixelShaderCache::InsertByteCode(key, value, value_size);
std::unique_ptr<u8[]> value(new u8[value_size]);
get_data(value.get());
PixelShaderCache::InsertByteCode(key, value.get(), value_size);
}
};
@ -353,9 +357,9 @@ void PixelShaderCache::Init()
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter());
}
// ONLY to be used during shutdown.

View File

@ -68,14 +68,15 @@ ID3D11Buffer*const& VertexShaderCache::GetConstantBuffer()
}
// this class will load the precompiled shaders into our cache
class VertexShaderCacheInserter : public LinearDiskCacheReader<VERTEXSHADERUID, u8>
class VertexShaderCacheInserter
{
public:
void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size)
template <typename F>
void operator()(const VERTEXSHADERUID& key, u32 value_size, F get_data) const
{
ID3D10Blob* blob = nullptr;
PD3D10CreateBlob(value_size, &blob);
memcpy(blob->GetBufferPointer(), value, value_size); // TODO: i would like to eliminate this memcpy
get_data((u8*)blob->GetBufferPointer()); // read data from file into blob
VertexShaderCache::InsertByteCode(key, SharedPtr<ID3D10Blob>::FromPtr(blob));
}
@ -176,9 +177,9 @@ void VertexShaderCache::Init()
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter());
}
void VertexShaderCache::Clear()

View File

@ -66,12 +66,16 @@ static LPDIRECT3DPIXELSHADER9 s_ClearProgram = NULL;
static LPDIRECT3DPIXELSHADER9 s_rgba6_to_rgb8 = NULL;
static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL;
class PixelShaderCacheInserter : public LinearDiskCacheReader<PIXELSHADERUID, u8>
class PixelShaderCacheInserter
{
public:
void Read(const PIXELSHADERUID &key, const u8 *value, u32 value_size)
template <typename F>
void operator()(const PIXELSHADERUID& key, u32 value_size, F get_data) const
{
PixelShaderCache::InsertByteCode(key, value, value_size, false);
std::unique_ptr<u8[]> value(new u8[value_size]);
get_data(value.get());
PixelShaderCache::InsertByteCode(key, value.get(), value_size, false);
}
};
@ -281,8 +285,8 @@ void PixelShaderCache::Init()
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter());
}
// ONLY to be used during shutdown.

View File

@ -57,12 +57,16 @@ LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader()
}
// this class will load the precompiled shaders into our cache
class VertexShaderCacheInserter : public LinearDiskCacheReader<VERTEXSHADERUID, u8>
class VertexShaderCacheInserter
{
public:
void Read(const VERTEXSHADERUID &key, const u8 *value, u32 value_size)
template <typename F>
void operator()(const VERTEXSHADERUID& key, u32 value_size, F get_data) const
{
VertexShaderCache::InsertByteCode(key, value, value_size, false);
std::unique_ptr<u8[]> value(new u8[value_size]);
get_data(value.get());
VertexShaderCache::InsertByteCode(key, value.get(), value_size, false);
}
};
@ -148,9 +152,9 @@ void VertexShaderCache::Init()
char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter());
}
void VertexShaderCache::Clear()