Implement new gpu program interface in opengl driver

--HG--
branch : multipass-stereo
This commit is contained in:
kaetemi 2013-09-07 21:30:40 +02:00
parent 1fa02cae9e
commit 350b580085
11 changed files with 157 additions and 61 deletions

View file

@ -57,7 +57,7 @@ public:
// The virtual dtor is important.
virtual ~IGPUProgramDrvInfos(void);
virtual uint getParamIdx(char *name) const { return ~0; }; // STEREO_TODO
virtual uint getParamIdx(char *name) const = 0;
};
class CGPUProgramSource;

View file

@ -53,11 +53,13 @@ public:
/// Minimal required profile for this GPU program
IGPUProgram::TProfile Profile;
const char *CodePtr;
const char *SourcePtr;
size_t SourceLen;
/// Copy the source code string
inline void setCode(const char *source) { CodeCopy = source; CodePtr = &source[0]; }
inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); }
/// Set pointer to source code string without copying the string
inline void setCodePtr(const char *sourcePtr) { CodeCopy.clear(); CodePtr = sourcePtr; }
inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; }
inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); }
/// CVertexProgramInfo/CPixelProgramInfo/... NeL features
uint Features;
@ -66,7 +68,7 @@ public:
std::map<std::string, uint> ParamIndices;
private:
std::string CodeCopy;
std::string SourceCopy;
}; /* class CGPUProgramSource */

View file

@ -33,7 +33,7 @@ namespace NL3D
{
// ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x6c; // pixel program interface
const uint32 IDriver::InterfaceVersion = 0x6d; // gpu program interface
// ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )

View file

@ -2573,14 +2573,6 @@ CVertexBuffer::TVertexColorType CDriverGL::getVertexColorFormat() const
return CVertexBuffer::TRGBA;
}
// ***************************************************************************
bool CDriverGL::activeShader(CShader * /* shd */)
{
H_AUTO_OGL(CDriverGL_activeShader)
return false;
}
// ***************************************************************************
void CDriverGL::startBench (bool wantStandardDeviation, bool quick, bool reset)
{

View file

@ -406,8 +406,6 @@ public:
virtual CMatrix getViewMatrix() const;
virtual bool activeShader(CShader *shd);
virtual void forceNormalize(bool normalize)
{
_ForceNormalize= normalize;
@ -1349,7 +1347,7 @@ private:
/// \name Pixel program implementation
// @{
bool activeARBPixelProgram (CPixelProgram *program);
bool setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
//@}
@ -1530,7 +1528,7 @@ private:
};
// ***************************************************************************
class CVertexProgamDrvInfosGL : public IVertexProgramDrvInfos
class CVertexProgamDrvInfosGL : public IGPUProgramDrvInfos
{
public:
// The GL Id.
@ -1551,18 +1549,36 @@ public:
// The gl id is auto created here.
CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it);
CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
virtual uint getParamIdx(char *name) const
{
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> ParamIndices;
};
// ***************************************************************************
class CPixelProgamDrvInfosGL : public IPixelProgramDrvInfos
class CPixelProgamDrvInfosGL : public IGPUProgramDrvInfos
{
public:
// The GL Id.
GLuint ID;
// The gl id is auto created here.
CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it);
CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
virtual uint getParamIdx(char *name) const
{
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> ParamIndices;
};
#ifdef NL_STATIC

View file

@ -50,7 +50,7 @@ namespace NLDRIVERGL {
#endif
// ***************************************************************************
CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it)
CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it)
{
H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL)
// Extension must exist
@ -109,25 +109,25 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program)
if (program->_DrvInfo==NULL)
{
// Insert into driver list. (so it is deleted when driver is deleted).
ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end(), (NL3D::IPixelProgramDrvInfos*)NULL);
ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
// Create a driver info
*it = drvInfo = new CPixelProgamDrvInfosGL (this, it);
*it = drvInfo = new CPixelProgamDrvInfosGL(this, it);
// Set the pointer
program->_DrvInfo=drvInfo;
program->_DrvInfo = drvInfo;
if(!setupARBPixelProgram(program, drvInfo->ID))
if (!setupPixelProgram(program, drvInfo->ID))
{
delete drvInfo;
program->_DrvInfo = NULL;
_PixelPrgDrvInfos.erase(it);
_GPUPrgDrvInfos.erase(it);
return false;
}
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CPixelProgamDrvInfosGL*>((IPixelProgramDrvInfos*)program->_DrvInfo);
drvInfo=safe_cast<CPixelProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
}
glEnable( GL_FRAGMENT_PROGRAM_ARB );
_PixelProgramEnabled = true;
@ -148,15 +148,31 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program)
}
// ***************************************************************************
bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/)
bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/)
{
H_AUTO_OGL(CDriverGL_setupARBPixelProgram)
const std::string &code = program->getProgram();
CPixelProgamDrvInfosGL *drvInfo = static_cast<CPixelProgamDrvInfosGL *>((IGPUProgramDrvInfos *)program->_DrvInfo);
// Find a supported pixel program profile
CGPUProgramSource *source = NULL;
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
{
if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile))
{
source = program->getProgramSource()->Sources[i];
}
}
if (!source)
{
nlwarning("No supported source profile for pixel program");
return false;
}
// Compile the program
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id);
glGetError();
nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() );
nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
@ -165,25 +181,25 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*,
GLint position;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position);
nlassert(position != -1); // there was an error..
nlassert(position < (GLint) code.size());
nlassert(position < (GLint) source->SourceLen);
uint line = 0;
const char *lineStart = program->getProgram().c_str();
const char *lineStart = source->SourcePtr;
for(uint k = 0; k < (uint) position; ++k)
{
if (code[k] == '\n')
if (source->SourcePtr[k] == '\n')
{
lineStart = code.c_str() + k;
lineStart = source->SourcePtr + k;
++line;
}
}
nlwarning("ARB fragment program parse error at line %d.", (int) line);
// search end of line
const char *lineEnd = code.c_str() + code.size();
for(uint k = position; k < code.size(); ++k)
const char *lineEnd = source->SourcePtr + source->SourceLen;
for(uint k = position; k < source->SourceLen; ++k)
{
if (code[k] == '\n')
if (source->SourcePtr[k] == '\n')
{
lineEnd = code.c_str() + k;
lineEnd = source->SourcePtr + k;
break;
}
}
@ -196,6 +212,13 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*,
nlassert(0);
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source->DisplayName.c_str(), source->Features);
return true;
}

View file

@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader()
CVertexProgram *vp = _LastSetuppedVP;
if (vp)
{
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IGPUProgramDrvInfos *) vp->_DrvInfo);
if (drvInfo)
{
// Disable all VertexAttribs.
@ -1396,7 +1396,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
CVertexProgram *vp = _LastSetuppedVP;
if (!vp) return;
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IGPUProgramDrvInfos *) vp->_DrvInfo);
if (!drvInfo) return;
uint32 flags= vb.VertexFormat;

View file

@ -41,7 +41,7 @@ namespace NLDRIVERGL {
#endif
// ***************************************************************************
CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it)
CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL(CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it)
{
H_AUTO_OGL(CVertexProgamDrvInfosGL_CVertexProgamDrvInfosGL);
@ -105,13 +105,28 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
// Program setuped ?
if (program->_DrvInfo==NULL)
{
// Find nelvp
CGPUProgramSource *source = NULL;
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
{
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
{
source = program->getProgramSource()->Sources[i];
}
}
if (!source)
{
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
return false;
}
/** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..).
* There are some incompatibilities.
*/
CVPParser parser;
CVPParser::TProgram parsedProgram;
std::string errorOutput;
bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput);
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
if (!result)
{
nlwarning("Unable to parse a vertex program :");
@ -123,7 +138,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
}
// Insert into driver list. (so it is deleted when driver is deleted).
ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL);
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
// Create a driver info
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
@ -132,7 +147,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
program->_DrvInfo=drvInfo;
// Compile the program
nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)program->getProgram().length(), (const GLubyte*)program->getProgram().c_str());
nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr);
// Get loading error code
GLint errorOff;
@ -142,8 +157,8 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
if (errorOff>=0)
{
// String length
uint length = (uint)program->getProgram ().length();
const char* sString= program->getProgram ().c_str();
uint length = (uint)source->SourceLen;
const char* sString = source->SourcePtr;
// Line count and char count
uint line=1;
@ -176,13 +191,19 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source->DisplayName.c_str(), source->Features);
// Setup ok
return true;
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IVertexProgramDrvInfos*)program->_DrvInfo);
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
}
// Setup this program
@ -1503,11 +1524,26 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
// Program setuped ?
if (program->_DrvInfo==NULL)
{
// Find nelvp
CGPUProgramSource *source = NULL;
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
{
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
{
source = program->getProgramSource()->Sources[i];
}
}
if (!source)
{
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
return false;
}
// try to parse the program
CVPParser parser;
CVPParser::TProgram parsedProgram;
std::string errorOutput;
bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput);
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
if (!result)
{
nlwarning("Unable to parse a vertex program.");
@ -1517,7 +1553,7 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
return false;
}
// Insert into driver list. (so it is deleted when driver is deleted).
ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL);
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
// Create a driver info
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
@ -1528,14 +1564,20 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
{
delete drvInfo;
program->_DrvInfo = NULL;
_VtxPrgDrvInfos.erase(it);
_GPUPrgDrvInfos.erase(it);
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source->DisplayName.c_str(), source->Features);
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IVertexProgramDrvInfos*)program->_DrvInfo);
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
}
glEnable( GL_VERTEX_PROGRAM_ARB );
_VertexProgramEnabled = true;
@ -1577,11 +1619,26 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
// Program setuped ?
if (program->_DrvInfo==NULL)
{
// Find nelvp
CGPUProgramSource *source = NULL;
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
{
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
{
source = program->getProgramSource()->Sources[i];
}
}
if (!source)
{
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
return false;
}
// try to parse the program
CVPParser parser;
CVPParser::TProgram parsedProgram;
std::string errorOutput;
bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput);
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
if (!result)
{
nlwarning("Unable to parse a vertex program.");
@ -1603,7 +1660,7 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
*/
// Insert into driver list. (so it is deleted when driver is deleted).
ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL);
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
// Create a driver info
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
@ -1614,14 +1671,20 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
{
delete drvInfo;
program->_DrvInfo = NULL;
_VtxPrgDrvInfos.erase(it);
_GPUPrgDrvInfos.erase(it);
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source->DisplayName.c_str(), source->Features);
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IVertexProgramDrvInfos*)program->_DrvInfo);
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
}
glEnable( GL_VERTEX_SHADER_EXT);

View file

@ -130,7 +130,7 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
{
nldebug("VR: arbfp1");
source->Profile = IGPUProgram::arbfp1;
source->setCodePtr(a_arbfp1);
source->setSourcePtr(a_arbfp1);
m_PixelProgram = new CPixelProgram(sourceCont);
}
/*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))

View file

@ -248,21 +248,21 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver)
{
nldebug("VR: fp40");
source->Profile = IGPUProgram::fp40;
source->setCodePtr(g_StereoOVR_fp40);
source->setSourcePtr(g_StereoOVR_fp40);
m_PixelProgram = new CPixelProgram(sourceCont);
}
else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
{
nldebug("VR: arbfp1");
source->Profile = IGPUProgram::arbfp1;
source->setCodePtr(g_StereoOVR_arbfp1);
source->setSourcePtr(g_StereoOVR_arbfp1);
m_PixelProgram = new CPixelProgram(sourceCont);
}
else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
{
nldebug("VR: ps_2_0");
source->Profile = IGPUProgram::ps_2_0;
source->setCodePtr(g_StereoOVR_ps_2_0);
source->setSourcePtr(g_StereoOVR_ps_2_0);
m_PixelProgram = new CPixelProgram(sourceCont);
}

View file

@ -39,7 +39,7 @@ CVertexProgram::CVertexProgram(const char *nelvp) : _Info(NULL)
_ProgramSource = new CGPUProgramSourceCont();
_ProgramSource->Sources.push_back(source);
source->Profile = IGPUProgram::nelvp;
source->setCode(nelvp);
source->setSource(nelvp);
source->Features = 0;
}