Use hashes for shader program lookup

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 10 years ago
parent f1f2e6fa1d
commit 0299519116

@ -663,10 +663,10 @@ bool CDriverGL3::release()
m_UserPixelProgram = NULL;
// Delete all cached programs
for (std::set<CVPBuiltin>::iterator it(m_VPBuiltinCache.begin()), end(m_VPBuiltinCache.end()); it != end; ++it)
for (std::unordered_set<CVPBuiltin>::iterator it(m_VPBuiltinCache.begin()), end(m_VPBuiltinCache.end()); it != end; ++it)
delete it->VertexProgram;
m_VPBuiltinCache.clear();
for (std::set<CPPBuiltin>::iterator it(m_PPBuiltinCache.begin()), end(m_PPBuiltinCache.end()); it != end; ++it)
for (std::unordered_set<CPPBuiltin>::iterator it(m_PPBuiltinCache.begin()), end(m_PPBuiltinCache.end()); it != end; ++it)
delete it->PixelProgram;
m_PPBuiltinCache.clear();

@ -35,6 +35,8 @@
# endif //XF86VIDMODE
#endif // NL_OS_UNIX
#include <unordered_set>
#include "nel/misc/matrix.h"
#include "nel/misc/smart_ptr.h"
#include "nel/misc/rgba.h"
@ -1302,9 +1304,9 @@ private:
NLMISC::CRefPtr<CPixelProgram> m_DriverPixelProgram;
friend class CPPBuiltin;
std::set<CPPBuiltin> m_PPBuiltinCache;
std::unordered_set<CPPBuiltin> m_PPBuiltinCache;
std::set<CVPBuiltin> m_VPBuiltinCache;
std::unordered_set<CVPBuiltin> m_VPBuiltinCache;
CVPBuiltin m_VPBuiltinCurrent;
bool m_VPBuiltinTouched;

@ -18,6 +18,8 @@
#include <sstream>
#include "nel/misc/wang_hash.h"
#include "nel/3d/vertex_program.h"
#include "nel/3d/light.h"
@ -95,6 +97,70 @@ bool operator<(const CPPBuiltin &left, const CPPBuiltin &right)
return false;
}
bool operator==(const CPPBuiltin &left, const CPPBuiltin &right)
{
// Material state
if (left.Shader != right.Shader)
return false;
if (left.Flags != right.Flags)
return false;
if (left.TextureActive != right.TextureActive)
return false;
if (left.TexSamplerMode != right.TexSamplerMode)
return false;
uint maxTex = maxTextures(left.Shader);
if (useTexEnv(left.Shader))
for (uint stage = 0; stage < maxTex; ++stage)
if (left.TexEnvMode[stage] != right.TexEnvMode[stage])
return false;
// Driver state
if (left.VertexFormat != right.VertexFormat)
return false;
if (left.Fog != right.Fog)
return false;
return true;
}
#ifdef NL_STATIC
} // NLDRIVERGL3
#endif
} // NL3D
namespace std {
size_t hash<NL3D::CPPBuiltin>::operator()(const NL3D::CPPBuiltin & v) const
{
uint32_t h;
// Material state
h = NLMISC::wangHash((uint32)v.Shader);
h = NLMISC::wangHash(h ^ (uint32)v.Flags);
h = NLMISC::wangHash(h ^ (uint32)v.TextureActive);
h = NLMISC::wangHash(h ^ (uint32)v.TexSamplerMode);
uint maxTex = NL3D::maxTextures(v.Shader);
if (NL3D::useTexEnv(v.Shader))
for (uint stage = 0; stage < maxTex; ++stage)
h = NLMISC::wangHash(h ^ (uint32)v.TexEnvMode[stage]);
// Driver state
h = NLMISC::wangHash(h ^ (uint32)v.VertexFormat);
h = NLMISC::wangHash(h ^ (uint32)v.Fog);
nlctassert(sizeof(size_t) > sizeof(uint32));
return (size_t)h;
}
}
namespace NL3D {
#ifdef NL_STATIC
namespace NLDRIVERGL3 {
#endif
namespace /* anonymous */ {
const char *s_ShaderNames[] =
@ -568,7 +634,7 @@ void CDriverGL3::generateBuiltinPixelProgram(CMaterial &mat)
CMaterialDrvInfosGL3 *matDrv = static_cast<CMaterialDrvInfosGL3 *>((IMaterialDrvInfos *)(mat._MatDrvInfo));
nlassert(matDrv);
std::set<CPPBuiltin>::iterator it = m_PPBuiltinCache.find(matDrv->PPBuiltin);
std::unordered_set<CPPBuiltin>::iterator it = m_PPBuiltinCache.find(matDrv->PPBuiltin);
if (it != m_PPBuiltinCache.end())
{
matDrv->PPBuiltin.PixelProgram = it->PixelProgram;

@ -50,6 +50,7 @@ struct CVPBuiltin
};
bool operator<(const CVPBuiltin &left, const CVPBuiltin &right);
bool operator==(const CVPBuiltin &left, const CVPBuiltin &right);
static const uint64 Sampler2D = 0;
static const uint64 SamplerCube = 1;
@ -78,6 +79,7 @@ struct CPPBuiltin
};
bool operator<(const CPPBuiltin &left, const CPPBuiltin &right);
bool operator==(const CPPBuiltin &left, const CPPBuiltin &right);
enum TAttribOffset
{
@ -123,6 +125,22 @@ inline bool hasFlag(uint32 data, uint32 flag)
} // NL3D
namespace std {
template <>
struct hash<NL3D::CVPBuiltin>
{
size_t operator()(const NL3D::CVPBuiltin & v) const;
};
template <>
struct hash<NL3D::CPPBuiltin>
{
size_t operator()(const NL3D::CPPBuiltin & v) const;
};
}
#endif // NL_DRIVER_OPENGL_PROGRAM_H
/* end of file */

@ -18,6 +18,8 @@
#include <sstream>
#include "nel/misc/wang_hash.h"
#include "nel/3d/vertex_program.h"
#include "nel/3d/light.h"
@ -54,6 +56,60 @@ bool operator<(const CVPBuiltin &left, const CVPBuiltin &right)
return false;
}
bool operator==(const CVPBuiltin &left, const CVPBuiltin &right)
{
if (left.VertexFormat != right.VertexFormat)
return false;
if (left.Lighting != right.Lighting)
return false;
if (left.Lighting)
for (sint i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i)
if (left.LightMode[i] != right.LightMode[i])
return false;
for (sint i = 0; i < IDRV_MAT_MAXTEXTURES; ++i)
if (left.TexGenMode[i] != right.TexGenMode[i])
return false;
if (left.Specular != right.Specular)
return false;
if (left.Fog != right.Fog)
return false;
// if (left.VertexColorLighted != right.VertexColorLighted)
// return false;
return true;
}
#ifdef NL_STATIC
} // NLDRIVERGL3
#endif
} // NL3D
namespace std {
size_t hash<NL3D::CVPBuiltin>::operator()(const NL3D::CVPBuiltin & v) const
{
uint32_t h;
h = NLMISC::wangHash(((uint32)v.VertexFormat) | (v.Lighting ? (1 << 16) : 0) | (v.Specular ? (1 << 17) : 0) | (v.Fog ? (1 << 18) : 0));
if (v.Lighting)
for (sint i = 0; i < NL_OPENGL3_MAX_LIGHT; ++i)
h = NLMISC::wangHash(h ^ v.LightMode[i]);
for (sint i = 0; i < NL3D::IDRV_MAT_MAXTEXTURES; ++i)
h = NLMISC::wangHash(h ^ v.TexGenMode[i]);
nlctassert(sizeof(size_t) > sizeof(uint32));
return (size_t)h;
}
}
namespace NL3D {
#ifdef NL_STATIC
namespace NLDRIVERGL3 {
#endif
namespace /* anonymous */ {
void vpLightUniforms(std::stringstream &ss, const CVPBuiltin &desc, int i)
@ -316,7 +372,7 @@ void vpGenerate(std::string &result, const CVPBuiltin &desc)
void CDriverGL3::generateBuiltinVertexProgram()
{
std::set<CVPBuiltin>::iterator it = m_VPBuiltinCache.find(m_VPBuiltinCurrent);
std::unordered_set<CVPBuiltin>::iterator it = m_VPBuiltinCache.find(m_VPBuiltinCurrent);
if (it != m_VPBuiltinCache.end())
{
m_VPBuiltinCurrent.VertexProgram = it->VertexProgram;

Loading…
Cancel
Save