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

@ -32,6 +32,7 @@ enum nzOpenGLExtension
nzOpenGLExtension_DrawInstanced, nzOpenGLExtension_DrawInstanced,
nzOpenGLExtension_FP64, nzOpenGLExtension_FP64,
nzOpenGLExtension_FrameBufferObject, nzOpenGLExtension_FrameBufferObject,
nzOpenGLExtension_GetProgramBinary,
nzOpenGLExtension_InstancedArray, nzOpenGLExtension_InstancedArray,
nzOpenGLExtension_PixelBufferObject, nzOpenGLExtension_PixelBufferObject,
nzOpenGLExtension_SamplerObjects, nzOpenGLExtension_SamplerObjects,
@ -202,6 +203,7 @@ NAZARA_API extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
NAZARA_API extern PFNGLGETERRORPROC glGetError; NAZARA_API extern PFNGLGETERRORPROC glGetError;
NAZARA_API extern PFNGLGETFLOATVPROC glGetFloatv; NAZARA_API extern PFNGLGETFLOATVPROC glGetFloatv;
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv; NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
NAZARA_API extern PFNGLGETPROGRAMBINARYPROC glGetProgramBinary;
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv; NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
NAZARA_API extern PFNGLGETQUERYIVPROC glGetQueryiv; NAZARA_API extern PFNGLGETQUERYIVPROC glGetQueryiv;
@ -227,6 +229,8 @@ NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei; NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
NAZARA_API extern PFNGLPOINTSIZEPROC glPointSize; NAZARA_API extern PFNGLPOINTSIZEPROC glPointSize;
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode; NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
NAZARA_API extern PFNGLPROGRAMBINARYPROC glProgramBinary;
NAZARA_API extern PFNGLPROGRAMPARAMETERIPROC glProgramParameteri;
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d; NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f; NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i; NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;

View File

@ -8,6 +8,7 @@
#define NAZARA_SHADER_HPP #define NAZARA_SHADER_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Color.hpp> #include <Nazara/Core/Color.hpp>
#include <Nazara/Core/NonCopyable.hpp> #include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/Resource.hpp> #include <Nazara/Core/Resource.hpp>
@ -42,6 +43,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
void Destroy(); void Destroy();
NzByteArray GetBinary() const;
nzUInt32 GetFlags() const; nzUInt32 GetFlags() const;
NzString GetLog() const; NzString GetLog() const;
nzShaderLanguage GetLanguage() const; nzShaderLanguage GetLanguage() const;
@ -51,6 +53,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
bool HasUniform(const NzString& name) const; bool HasUniform(const NzString& name) const;
bool IsBinaryRetrievable() const;
bool IsCompiled() const; bool IsCompiled() const;
bool IsLoaded(nzShaderType type) const; bool IsLoaded(nzShaderType type) const;
bool IsValid() const; bool IsValid() const;

View File

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

View File

@ -51,6 +51,9 @@ bool NzGLSLShader::Compile()
m_idCache.clear(); m_idCache.clear();
m_textures.clear(); m_textures.clear();
if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary))
glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
glLinkProgram(m_program); glLinkProgram(m_program);
GLint success; GLint success;
@ -170,6 +173,32 @@ void NzGLSLShader::Destroy()
NzOpenGL::DeleteProgram(m_program); 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 NzString NzGLSLShader::GetLog() const
{ {
return m_log; return m_log;
@ -219,6 +248,11 @@ int NzGLSLShader::GetUniformLocation(nzShaderUniform uniform) const
return m_uniformLocations[uniform]; return m_uniformLocations[uniform];
} }
bool NzGLSLShader::IsBinaryRetrievable() const
{
return NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary);
}
bool NzGLSLShader::IsLoaded(nzShaderType type) const bool NzGLSLShader::IsLoaded(nzShaderType type) const
{ {
return m_shaders[type] != 0; return m_shaders[type] != 0;

View File

@ -31,12 +31,14 @@ class NzGLSLShader : public NzAbstractShader, NzResourceListener
bool Create(); bool Create();
void Destroy(); void Destroy();
NzByteArray GetBinary() const;
NzString GetLog() const; NzString GetLog() const;
nzShaderLanguage GetLanguage() const; nzShaderLanguage GetLanguage() const;
NzString GetSourceCode(nzShaderType type) const; NzString GetSourceCode(nzShaderType type) const;
int GetUniformLocation(const NzString& name) const; int GetUniformLocation(const NzString& name) const;
int GetUniformLocation(nzShaderUniform uniform) const; int GetUniformLocation(nzShaderUniform uniform) const;
bool IsBinaryRetrievable() const;
bool IsLoaded(nzShaderType type) const; bool IsLoaded(nzShaderType type) const;
bool Load(nzShaderType type, const NzString& source); 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 // InstancedArray
if (s_openglVersion >= 330) if (s_openglVersion >= 330)
{ {
@ -1480,6 +1497,7 @@ PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr; PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETFLOATVPROC glGetFloatv = nullptr; PFNGLGETFLOATVPROC glGetFloatv = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr; PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMBINARYPROC glGetProgramBinary = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr; PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr;
PFNGLGETQUERYIVPROC glGetQueryiv = nullptr; PFNGLGETQUERYIVPROC glGetQueryiv = nullptr;
@ -1505,6 +1523,8 @@ PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPIXELSTOREIPROC glPixelStorei = nullptr; PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
PFNGLPOINTSIZEPROC glPointSize = nullptr; PFNGLPOINTSIZEPROC glPointSize = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr; PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMBINARYPROC glProgramBinary = nullptr;
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr; PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr; PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = 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 nzUInt32 NzShader::GetFlags() const
{ {
return m_flags; return m_flags;
@ -211,6 +236,19 @@ bool NzShader::HasUniform(const NzString& name) const
return m_impl->GetUniformLocation(name) != -1; 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 bool NzShader::IsCompiled() const
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE