Moved VertexDeclarationCache to its own header and source file.

TRAC #22016 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1490 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e569fc52
......@@ -267,6 +267,8 @@
'libGLESv2/renderer/Renderer9.h',
'libGLESv2/renderer/renderer9_utils.cpp',
'libGLESv2/renderer/renderer9_utils.h',
'libGLESv2/renderer/RenderStateCache.cpp',
'libGLESv2/renderer/RenderStateCache.h',
'libGLESv2/renderer/RenderTarget.h',
'libGLESv2/renderer/RenderTarget11.h',
'libGLESv2/renderer/RenderTarget11.cpp',
......@@ -280,8 +282,8 @@
'libGLESv2/renderer/SwapChain11.h',
'libGLESv2/renderer/TextureStorage.cpp',
'libGLESv2/renderer/TextureStorage.h',
'libGLESv2/renderer/RenderStateCache.cpp',
'libGLESv2/renderer/RenderStateCache.h',
'libGLESv2/renderer/VertexDeclarationCache.cpp',
'libGLESv2/renderer/VertexDeclarationCache.h',
'libGLESv2/ResourceManager.cpp',
'libGLESv2/ResourceManager.h',
'libGLESv2/Shader.cpp',
......
......@@ -7,7 +7,6 @@
// Program.cpp: Implements the gl::Program class. Implements GL program objects
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "common/debug.h"
......
......@@ -8,7 +8,6 @@
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
#include "libGLESv2/BinaryStream.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "common/debug.h"
......
......@@ -18,6 +18,7 @@
#include <string>
#include <vector>
#include "libGLESv2/Program.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/D3DConstantTable.h"
#include "libGLESv2/mathutil.h"
......
......@@ -13,7 +13,6 @@
#include "libGLESv2/renderer/Renderer9.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/main.h"
......
......@@ -258,6 +258,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClCompile Include="renderer\SwapChain11.cpp" />
<ClCompile Include="renderer\SwapChain9.cpp" />
<ClCompile Include="renderer\TextureStorage.cpp" />
<ClCompile Include="renderer\VertexDeclarationCache.cpp" />
<ClCompile Include="ResourceManager.cpp" />
<ClCompile Include="Shader.cpp" />
<ClCompile Include="Texture.cpp" />
......@@ -302,6 +303,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClInclude Include="renderer\SwapChain11.h" />
<ClInclude Include="renderer\SwapChain9.h" />
<ClInclude Include="renderer\TextureStorage.h" />
<ClInclude Include="renderer\VertexDeclarationCache.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="ResourceManager.h" />
<ClInclude Include="Shader.h" />
......
......@@ -128,6 +128,9 @@
<ClCompile Include="renderer\RenderTarget11.cpp">
<Filter>Renderer</Filter>
</ClCompile>
<ClCompile Include="renderer\VertexDeclarationCache.cpp">
<Filter>Renderer</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BinaryStream.h">
......@@ -262,6 +265,9 @@
<ClInclude Include="renderer\RenderTarget11.h">
<Filter>Renderer</Filter>
</ClInclude>
<ClInclude Include="renderer\VertexDeclarationCache.h">
<Filter>Renderer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="libGLESv2.def">
......@@ -271,4 +277,4 @@
<ItemGroup>
<ResourceCompile Include="libGLESv2.rc" />
</ItemGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -2417,203 +2417,4 @@ bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *s
return true;
}
VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
{
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
mVertexDeclCache[i].vertexDeclaration = NULL;
mVertexDeclCache[i].lruCount = 0;
}
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mAppliedVBs[i].serial = 0;
}
mLastSetVDecl = NULL;
mInstancingEnabled = true;
}
VertexDeclarationCache::~VertexDeclarationCache()
{
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
if (mVertexDeclCache[i].vertexDeclaration)
{
mVertexDeclCache[i].vertexDeclaration->Release();
}
}
}
GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, gl::TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
{
*repeatDraw = 1;
int indexedAttribute = gl::MAX_VERTEX_ATTRIBS;
int instancedAttribute = gl::MAX_VERTEX_ATTRIBS;
if (instances > 0)
{
// Find an indexed attribute to be mapped to D3D stream 0
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].active)
{
if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
if (attributes[i].divisor == 0)
{
indexedAttribute = i;
}
}
else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
if (attributes[i].divisor != 0)
{
instancedAttribute = i;
}
}
else break; // Found both an indexed and instanced attribute
}
}
if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
return GL_INVALID_OPERATION;
}
}
D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].active)
{
int stream = i;
if (instances > 0)
{
// Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
*repeatDraw = instances;
}
else
{
if (i == indexedAttribute)
{
stream = 0;
}
else if (i == 0)
{
stream = indexedAttribute;
}
UINT frequency = 1;
if (attributes[i].divisor == 0)
{
frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
}
else
{
frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
}
device->SetStreamSourceFreq(stream, frequency);
mInstancingEnabled = true;
}
}
if (mAppliedVBs[stream].serial != attributes[i].serial ||
mAppliedVBs[stream].stride != attributes[i].stride ||
mAppliedVBs[stream].offset != attributes[i].offset)
{
device->SetStreamSource(stream, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
mAppliedVBs[stream].serial = attributes[i].serial;
mAppliedVBs[stream].stride = attributes[i].stride;
mAppliedVBs[stream].offset = attributes[i].offset;
}
element->Stream = stream;
element->Offset = 0;
element->Type = attributes[i].type;
element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD;
element->UsageIndex = programBinary->getSemanticIndex(i);
element++;
}
}
if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
if (mInstancingEnabled)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
device->SetStreamSourceFreq(i, 1);
}
mInstancingEnabled = false;
}
}
static const D3DVERTEXELEMENT9 end = D3DDECL_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;
if(entry->vertexDeclaration != mLastSetVDecl)
{
device->SetVertexDeclaration(entry->vertexDeclaration);
mLastSetVDecl = entry->vertexDeclaration;
}
return GL_NO_ERROR;
}
}
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;
// mLastSetVDecl is set to the replacement, so we don't have to worry
// about it.
}
memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
device->SetVertexDeclaration(lastCache->vertexDeclaration);
mLastSetVDecl = lastCache->vertexDeclaration;
lastCache->lruCount = ++mMaxLru;
return GL_NO_ERROR;
}
void VertexDeclarationCache::markStateDirty()
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mAppliedVBs[i].serial = 0;
}
mLastSetVDecl = NULL;
mInstancingEnabled = true; // Forces it to be disabled when not used
}
}
\ No newline at end of file
......@@ -24,8 +24,8 @@
#include "common/angleutils.h"
#include "libGLESv2/renderer/ShaderCache.h"
#include "libGLESv2/renderer/VertexDeclarationCache.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Context.h"
namespace gl
{
......@@ -35,41 +35,6 @@ class VertexDataManager;
namespace rx
{
// Helper class to construct and cache vertex declarations
class VertexDeclarationCache
{
public:
VertexDeclarationCache();
~VertexDeclarationCache();
GLenum applyDeclaration(IDirect3DDevice9 *device, gl::TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
void markStateDirty();
private:
UINT mMaxLru;
enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 };
struct VBData
{
unsigned int serial;
unsigned int stride;
unsigned int offset;
};
VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS];
IDirect3DVertexDeclaration9 *mLastSetVDecl;
bool mInstancingEnabled;
struct VertexDeclCacheEntry
{
D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1];
UINT lruCount;
IDirect3DVertexDeclaration9 *vertexDeclaration;
} mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
};
class Renderer9 : public Renderer
{
public:
......
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations.
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexDataManager.h"
#include "libGLESv2/renderer/VertexDeclarationCache.h"
namespace rx
{
VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
{
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
mVertexDeclCache[i].vertexDeclaration = NULL;
mVertexDeclCache[i].lruCount = 0;
}
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mAppliedVBs[i].serial = 0;
}
mLastSetVDecl = NULL;
mInstancingEnabled = true;
}
VertexDeclarationCache::~VertexDeclarationCache()
{
for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
{
if (mVertexDeclCache[i].vertexDeclaration)
{
mVertexDeclCache[i].vertexDeclaration->Release();
}
}
}
GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, gl::TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
{
*repeatDraw = 1;
int indexedAttribute = gl::MAX_VERTEX_ATTRIBS;
int instancedAttribute = gl::MAX_VERTEX_ATTRIBS;
if (instances > 0)
{
// Find an indexed attribute to be mapped to D3D stream 0
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].active)
{
if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
if (attributes[i].divisor == 0)
{
indexedAttribute = i;
}
}
else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
if (attributes[i].divisor != 0)
{
instancedAttribute = i;
}
}
else break; // Found both an indexed and instanced attribute
}
}
if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
return GL_INVALID_OPERATION;
}
}
D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].active)
{
int stream = i;
if (instances > 0)
{
// Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
*repeatDraw = instances;
}
else
{
if (i == indexedAttribute)
{
stream = 0;
}
else if (i == 0)
{
stream = indexedAttribute;
}
UINT frequency = 1;
if (attributes[i].divisor == 0)
{
frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
}
else
{
frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
}
device->SetStreamSourceFreq(stream, frequency);
mInstancingEnabled = true;
}
}
if (mAppliedVBs[stream].serial != attributes[i].serial ||
mAppliedVBs[stream].stride != attributes[i].stride ||
mAppliedVBs[stream].offset != attributes[i].offset)
{
device->SetStreamSource(stream, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
mAppliedVBs[stream].serial = attributes[i].serial;
mAppliedVBs[stream].stride = attributes[i].stride;
mAppliedVBs[stream].offset = attributes[i].offset;
}
element->Stream = stream;
element->Offset = 0;
element->Type = attributes[i].type;
element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD;
element->UsageIndex = programBinary->getSemanticIndex(i);
element++;
}
}
if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
{
if (mInstancingEnabled)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
device->SetStreamSourceFreq(i, 1);
}
mInstancingEnabled = false;
}
}
static const D3DVERTEXELEMENT9 end = D3DDECL_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;
if(entry->vertexDeclaration != mLastSetVDecl)
{
device->SetVertexDeclaration(entry->vertexDeclaration);
mLastSetVDecl = entry->vertexDeclaration;
}
return GL_NO_ERROR;
}
}
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;
// mLastSetVDecl is set to the replacement, so we don't have to worry
// about it.
}
memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
device->SetVertexDeclaration(lastCache->vertexDeclaration);
mLastSetVDecl = lastCache->vertexDeclaration;
lastCache->lruCount = ++mMaxLru;
return GL_NO_ERROR;
}
void VertexDeclarationCache::markStateDirty()
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mAppliedVBs[i].serial = 0;
}
mLastSetVDecl = NULL;
mInstancingEnabled = true; // Forces it to be disabled when not used
}
}
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations.
#ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
#include "libGLESv2/Context.h"
namespace gl
{
class VertexDataManager;
}
namespace rx
{
class VertexDeclarationCache
{
public:
VertexDeclarationCache();
~VertexDeclarationCache();
GLenum applyDeclaration(IDirect3DDevice9 *device, gl::TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
void markStateDirty();
private:
UINT mMaxLru;
enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 };
struct VBData
{
unsigned int serial;
unsigned int stride;
unsigned int offset;
};
VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS];
IDirect3DVertexDeclaration9 *mLastSetVDecl;
bool mInstancingEnabled;
struct VertexDeclCacheEntry
{
D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1];
UINT lruCount;
IDirect3DVertexDeclaration9 *vertexDeclaration;
} mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
};
}
#endif // LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
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