Commit 2cec2f3a by jbauman@chromium.org

Profiling shows that creating and destroying vertex declarations is extremely…

Profiling shows that creating and destroying vertex declarations is extremely expensive, so we can keep a 16-element cache around to speed that up. BUG= TEST=JSGameBench Review URL: http://codereview.appspot.com/4358051 git-svn-id: https://angleproject.googlecode.com/svn/trunk@609 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 6cfe6787
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 606 #define BUILD_REVISION 609
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -26,13 +26,18 @@ namespace ...@@ -26,13 +26,18 @@ namespace
namespace gl namespace gl
{ {
VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device) VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device), mMaxLru(0)
{ {
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
mDirtyCurrentValue[i] = true; mDirtyCurrentValue[i] = true;
mCurrentValueBuffer[i] = NULL; mCurrentValueBuffer[i] = NULL;
} }
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
mVertexDeclCache[i].vertexDeclaration = NULL;
mVertexDeclCache[i].lruCount = 0;
}
const D3DCAPS9 &caps = context->getDeviceCaps(); const D3DCAPS9 &caps = context->getDeviceCaps();
checkVertexCaps(caps.DeclTypes); checkVertexCaps(caps.DeclTypes);
...@@ -48,6 +53,13 @@ VertexDataManager::~VertexDataManager() ...@@ -48,6 +53,13 @@ VertexDataManager::~VertexDataManager()
{ {
delete mCurrentValueBuffer[i]; delete mCurrentValueBuffer[i];
} }
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
if (mVertexDeclCache[i].vertexDeclaration)
{
mVertexDeclCache[i].vertexDeclaration->Release();
}
}
} }
UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute) UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
...@@ -509,7 +521,7 @@ unsigned int VertexDataManager::typeIndex(GLenum type) const ...@@ -509,7 +521,7 @@ unsigned int VertexDataManager::typeIndex(GLenum type) const
void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes) void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes)
{ {
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS]; D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0]; D3DVERTEXELEMENT9 *element = &elements[0];
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
...@@ -529,12 +541,39 @@ void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes) ...@@ -529,12 +541,39 @@ void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes)
} }
static const D3DVERTEXELEMENT9 end = D3DDECL_END(); static const D3DVERTEXELEMENT9 end = D3DDECL_END();
*element = end; *(element++) = end;
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
VertexDeclCacheEntry *entry = &mVertexDeclCache[i];
if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration)
{
entry->lruCount = ++mMaxLru;
mDevice->SetVertexDeclaration(entry->vertexDeclaration);
return;
}
}
VertexDeclCacheEntry *lastCache = mVertexDeclCache;
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
if (mVertexDeclCache[i].lruCount < lastCache->lruCount)
{
lastCache = &mVertexDeclCache[i];
}
}
if (lastCache->vertexDeclaration != NULL)
{
lastCache->vertexDeclaration->Release();
lastCache->vertexDeclaration = NULL;
}
IDirect3DVertexDeclaration9 *vertexDeclaration; memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
mDevice->CreateVertexDeclaration(elements, &vertexDeclaration); mDevice->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
mDevice->SetVertexDeclaration(vertexDeclaration); mDevice->SetVertexDeclaration(lastCache->vertexDeclaration);
vertexDeclaration->Release(); lastCache->lruCount = ++mMaxLru;
} }
VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL) VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL)
......
...@@ -163,6 +163,17 @@ class VertexDataManager ...@@ -163,6 +163,17 @@ class VertexDataManager
unsigned int typeIndex(GLenum type) const; unsigned int typeIndex(GLenum type) const;
const FormatConverter &formatConverter(const VertexAttribute &attribute) const; const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
UINT mMaxLru;
enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 16 };
struct VertexDeclCacheEntry
{
D3DVERTEXELEMENT9 cachedElements[MAX_VERTEX_ATTRIBS + 1];
UINT lruCount;
IDirect3DVertexDeclaration9 *vertexDeclaration;
} mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment