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:
parent
3d5d205c73
commit
306c3570d1
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -354,8 +358,8 @@ 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);
|
||||
|
||||
g_ps_disk_cache.OpenAndRead(cache_filename, PixelShaderCacheInserter());
|
||||
}
|
||||
|
||||
// ONLY to be used during shutdown.
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
@ -177,8 +178,8 @@ 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);
|
||||
|
||||
g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter());
|
||||
}
|
||||
|
||||
void VertexShaderCache::Clear()
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -149,8 +153,8 @@ 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);
|
||||
|
||||
g_vs_disk_cache.OpenAndRead(cache_filename, VertexShaderCacheInserter());
|
||||
}
|
||||
|
||||
void VertexShaderCache::Clear()
|
||||
|
|
Loading…
Reference in New Issue