Added methods to retrieve shader binary

Added support for GL_ARB_get_program_binary


Former-commit-id: 3c23cfd237680f7832d15279af9e4248f9fa4678
This commit is contained in:
Lynix
2013-08-01 23:22:48 +02:00
parent c276a4a623
commit d751718a16
7 changed files with 103 additions and 0 deletions

View File

@@ -25,12 +25,14 @@ class NzAbstractShader
virtual void Destroy() = 0;
virtual NzByteArray GetBinary() const = 0;
virtual NzString GetLog() const = 0;
virtual nzShaderLanguage GetLanguage() const = 0;
virtual NzString GetSourceCode(nzShaderType type) const = 0;
virtual int GetUniformLocation(const NzString& name) const = 0;
virtual int GetUniformLocation(nzShaderUniform uniform) const = 0;
virtual bool IsBinaryRetrievable() const = 0;
virtual bool IsLoaded(nzShaderType type) const = 0;
virtual bool Load(nzShaderType type, const NzString& source) = 0;

View File

@@ -51,6 +51,9 @@ bool NzGLSLShader::Compile()
m_idCache.clear();
m_textures.clear();
if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary))
glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
glLinkProgram(m_program);
GLint success;
@@ -170,6 +173,32 @@ void NzGLSLShader::Destroy()
NzOpenGL::DeleteProgram(m_program);
}
NzByteArray NzGLSLShader::GetBinary() const
{
NzByteArray byteArray;
NzContext::EnsureContext();
GLint binaryLength;
glGetProgramiv(m_program, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
if (binaryLength > 0)
{
byteArray.Resize(sizeof(nzUInt64) + binaryLength);
nzUInt8* ptr = byteArray.GetBuffer();
GLenum binaryFormat;
glGetProgramBinary(m_program, binaryLength, nullptr, &binaryFormat, &ptr[sizeof(nzUInt64)]);
// On stocke le format au début du binaire
nzUInt64* format = reinterpret_cast<nzUInt64*>(&ptr[0]);
*format = binaryFormat;
}
return byteArray;
}
NzString NzGLSLShader::GetLog() const
{
return m_log;
@@ -219,6 +248,11 @@ int NzGLSLShader::GetUniformLocation(nzShaderUniform uniform) const
return m_uniformLocations[uniform];
}
bool NzGLSLShader::IsBinaryRetrievable() const
{
return NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary);
}
bool NzGLSLShader::IsLoaded(nzShaderType type) const
{
return m_shaders[type] != 0;

View File

@@ -31,12 +31,14 @@ class NzGLSLShader : public NzAbstractShader, NzResourceListener
bool Create();
void Destroy();
NzByteArray GetBinary() const;
NzString GetLog() const;
nzShaderLanguage GetLanguage() const;
NzString GetSourceCode(nzShaderType type) const;
int GetUniformLocation(const NzString& name) const;
int GetUniformLocation(nzShaderUniform uniform) const;
bool IsBinaryRetrievable() const;
bool IsLoaded(nzShaderType type) const;
bool Load(nzShaderType type, const NzString& source);

View File

@@ -866,6 +866,23 @@ bool NzOpenGL::Initialize()
}
}
// GetProgramBinary
if (s_openglVersion >= 410 || IsSupported("GL_ARB_get_program_binary"))
{
try
{
glGetProgramBinary = reinterpret_cast<PFNGLGETPROGRAMBINARYPROC>(LoadEntry("glGetProgramBinary"));
glProgramBinary = reinterpret_cast<PFNGLPROGRAMBINARYPROC>(LoadEntry("glProgramBinary"));
glProgramParameteri = reinterpret_cast<PFNGLPROGRAMPARAMETERIPROC>(LoadEntry("glProgramParameteri"));
s_openGLextensions[nzOpenGLExtension_GetProgramBinary] = true;
}
catch (const std::exception& e)
{
NazaraWarning("Failed to load ARB_get_program_binary: (" + NzString(e.what()) + ")");
}
}
// InstancedArray
if (s_openglVersion >= 330)
{
@@ -1480,6 +1497,7 @@ PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETFLOATVPROC glGetFloatv = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMBINARYPROC glGetProgramBinary = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr;
PFNGLGETQUERYIVPROC glGetQueryiv = nullptr;
@@ -1505,6 +1523,8 @@ PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
PFNGLPOINTSIZEPROC glPointSize = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMBINARYPROC glProgramBinary = nullptr;
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr;

View File

@@ -106,6 +106,31 @@ void NzShader::Destroy()
}
}
NzByteArray NzShader::GetBinary() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return NzByteArray();
}
if (!m_compiled)
{
NazaraError("Shader is not compiled");
return NzByteArray();
}
if (!m_impl->IsBinaryRetrievable())
{
NazaraError("Shader binary is not retrievable");
return NzByteArray();
}
#endif
return m_impl->GetBinary();
}
nzUInt32 NzShader::GetFlags() const
{
return m_flags;
@@ -211,6 +236,19 @@ bool NzShader::HasUniform(const NzString& name) const
return m_impl->GetUniformLocation(name) != -1;
}
bool NzShader::IsBinaryRetrievable() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->IsBinaryRetrievable();
}
bool NzShader::IsCompiled() const
{
#if NAZARA_RENDERER_SAFE