GL3: Increase number of usable samplers in program from 4 to 32

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent 393d08532a
commit 5d542ed91e

@ -38,6 +38,8 @@
namespace NL3D {
static const uint32 IDRV_PROGRAM_MAXSAMPLERS = 32;
// List typedef.
class IDriver;
class IProgramDrvInfos;
@ -135,11 +137,67 @@ struct CProgramIndex
Constant1,
Constant2,
Constant3,
Constant4,
Constant5,
Constant6,
Constant7,
Constant8,
Constant9,
Constant10,
Constant11,
Constant12,
Constant13,
Constant14,
Constant15,
Constant16,
Constant17,
Constant18,
Constant19,
Constant20,
Constant21,
Constant22,
Constant23,
Constant24,
Constant25,
Constant26,
Constant27,
Constant28,
Constant29,
Constant30,
Constant31,
Sampler0,
Sampler1,
Sampler2,
Sampler3,
Sampler4,
Sampler5,
Sampler6,
Sampler7,
Sampler8,
Sampler9,
Sampler10,
Sampler11,
Sampler12,
Sampler13,
Sampler14,
Sampler15,
Sampler16,
Sampler17,
Sampler18,
Sampler19,
Sampler20,
Sampler21,
Sampler22,
Sampler23,
Sampler24,
Sampler25,
Sampler26,
Sampler27,
Sampler28,
Sampler29,
Sampler30,
Sampler31,
TexMatrix0,
TexMatrix1,
@ -147,43 +205,43 @@ struct CProgramIndex
TexMatrix3,
TexGen0ObjectPlaneS,
TexGen1ObjectPlaneS,
TexGen2ObjectPlaneS,
TexGen3ObjectPlaneS,
TexGen0ObjectPlaneT,
TexGen1ObjectPlaneT,
TexGen2ObjectPlaneT,
TexGen3ObjectPlaneT,
TexGen0ObjectPlaneP,
TexGen1ObjectPlaneP,
TexGen2ObjectPlaneP,
TexGen3ObjectPlaneP,
TexGen0ObjectPlaneQ,
TexGen1ObjectPlaneS,
TexGen1ObjectPlaneT,
TexGen1ObjectPlaneP,
TexGen1ObjectPlaneQ,
TexGen2ObjectPlaneS,
TexGen2ObjectPlaneT,
TexGen2ObjectPlaneP,
TexGen2ObjectPlaneQ,
TexGen3ObjectPlaneS,
TexGen3ObjectPlaneT,
TexGen3ObjectPlaneP,
TexGen3ObjectPlaneQ,
TexGen0EyePlaneS,
TexGen1EyePlaneS,
TexGen2EyePlaneS,
TexGen3EyePlaneS,
TexGen0EyePlaneT,
TexGen1EyePlaneT,
TexGen2EyePlaneT,
TexGen3EyePlaneT,
TexGen0EyePlaneP,
TexGen1EyePlaneP,
TexGen2EyePlaneP,
TexGen3EyePlaneP,
TexGen0EyePlaneQ,
TexGen1EyePlaneS,
TexGen1EyePlaneT,
TexGen1EyePlaneP,
TexGen1EyePlaneQ,
TexGen2EyePlaneS,
TexGen2EyePlaneT,
TexGen2EyePlaneP,
TexGen2EyePlaneQ,
TexGen3EyePlaneS,
TexGen3EyePlaneT,
TexGen3EyePlaneP,
TexGen3EyePlaneQ,
SelfIllumination,

@ -301,11 +301,6 @@ CDriverGL::CDriverGL()
for(i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
{
_MaterialAllTextureTouchedFlag |= IDRV_TOUCHED_TEX[i];
#ifdef GL_NONE
_CurrentTexAddrMode[i] = GL_NONE;
#else
_CurrentTexAddrMode[i] = 0;
#endif
}
_UserTexMatEnabled = 0;

@ -256,11 +256,6 @@ CDriverGL3::CDriverGL3()
for (i=0; i < IDRV_MAT_MAXTEXTURES; i++)
{
_MaterialAllTextureTouchedFlag|= IDRV_TOUCHED_TEX[i];
#ifdef GL_NONE
_CurrentTexAddrMode[i] = GL_NONE;
#else
_CurrentTexAddrMode[i] = 0;
#endif
}
for (i = 0; i < IDRV_MAT_MAXTEXTURES; i++)
@ -411,13 +406,15 @@ bool CDriverGL3::setupDisplay()
// Activate the default texture environnments for all stages.
//===========================================================
for (uint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage)
for (uint stage = 0; stage < IDRV_PROGRAM_MAXSAMPLERS; ++stage)
{
// init no texture.
_CurrentTexture[stage] = NULL;
_CurrentTextureInfoGL[stage] = NULL;
// texture are disabled in DriverGLStates.forceDefaults().
}
for (uint stage = 0; stage < IDRV_MAT_MAXTEXTURES; ++stage)
{
// init default env.
CMaterial::CTexEnv env; // envmode init to default.
env.ConstantColor.set(255,255,255,255);
@ -1187,7 +1184,8 @@ NLMISC::CRGBA CDriverGL3::getBlendConstantColor() const
uint CDriverGL3::getNbTextureStages() const
{
H_AUTO_OGL(CDriverGL3_getNbTextureStages)
return IDRV_MAT_MAXTEXTURES;
return IDRV_MAT_MAXTEXTURES; // Must return this for compatibility
}
// ***************************************************************************

@ -920,14 +920,8 @@ private:
/* NB : this pointers handles the caching of glBindTexture() and setTextureMode() calls.
*/
ITexture* _CurrentTexture[IDRV_MAT_MAXTEXTURES];
CTextureDrvInfosGL3* _CurrentTextureInfoGL[IDRV_MAT_MAXTEXTURES];
//CMaterial::CTexEnv _CurrentTexEnv[IDRV_MAT_MAXTEXTURES];
// Special Texture Environnement.
//CTexEnvSpecial _CurrentTexEnvSpecial[IDRV_MAT_MAXTEXTURES];
// Texture addressing mode
GLenum _CurrentTexAddrMode[IDRV_MAT_MAXTEXTURES];
ITexture* _CurrentTexture[IDRV_PROGRAM_MAXSAMPLERS];
CTextureDrvInfosGL3* _CurrentTextureInfoGL[IDRV_PROGRAM_MAXSAMPLERS];
// Anisotropic filtering value
float _AnisotropicFilter;

@ -605,9 +605,12 @@ bool registerGlExtensions(CGlExtensions &ext)
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &ext.EXTTextureFilterAnisotropicMaximum);
}
GLint nbFragmentTextureUnits;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &nbFragmentTextureUnits);
ext.NbFragmentTextureUnits = (nbFragmentTextureUnits > IDRV_MAT_MAXTEXTURES) ? IDRV_MAT_MAXTEXTURES : nbFragmentTextureUnits; // FIXME GL3
// Get the maximum fragment texture unites
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &ext.MaxFragmentTextureImageUnits);
if (ext.MaxFragmentTextureImageUnits < 8)
{
nlwarning("GL_MAX_TEXTURE_IMAGE_UNITS must be greater than or equal to 8, value returned by driver is %i", ext.MaxFragmentTextureImageUnits);
}
return true;
}

@ -38,7 +38,7 @@ struct CGlExtensions
// Required extensions
bool GLCore;
bool ARBSeparateShaderObjects;
uint NbFragmentTextureUnits;
GLint MaxFragmentTextureImageUnits;
// Optional extensions
bool EXTTextureCompressionS3TC;
@ -65,7 +65,7 @@ public:
// Fill all false by default.
GLCore = false;
ARBSeparateShaderObjects = false;
NbFragmentTextureUnits = 0;
MaxFragmentTextureImageUnits = 0;
EXTTextureCompressionS3TC = false;
EXTTextureFilterAnisotropic = false;
@ -99,8 +99,8 @@ public:
result += ARBMultiTexture ? "ARBMultiTexture " : "";
result += EXTTextureCompressionS3TC ? "EXTTextureCompressionS3TC " : "";
result += EXTTextureFilterAnisotropic ? "EXTTextureFilterAnisotropic (Maximum = " + NLMISC::toString(EXTTextureFilterAnisotropicMaximum) + ") " : "";
result += "texture stages(*) = ";
result += NLMISC::toString(NbFragmentTextureUnits);
result += "fragment texture units(*) = ";
result += NLMISC::toString(MaxFragmentTextureImageUnits);
#ifdef NL_OS_WINDOWS
result += "\n WindowsGL: ";

@ -45,6 +45,17 @@ uint maxTextures(CMaterial::TShader shader)
}
}
uint maxSamplers(CMaterial::TShader shader, CGlExtensions &glext)
{
switch (shader)
{
case CMaterial::LightMap:
return std::min((GLint)IDRV_PROGRAM_MAXSAMPLERS, glext.MaxFragmentTextureImageUnits);
default:
return maxTextures(shader);
}
}
bool useTexEnv(CMaterial::TShader shader)
{
return shader == CMaterial::Normal
@ -67,12 +78,9 @@ bool operator<(const CPPBuiltin &left, const CPPBuiltin &right)
return left.Flags < right.Flags;
if (left.TextureActive != right.TextureActive)
return left.TextureActive < right.TextureActive;
if (left.TexSamplerMode != right.TexSamplerMode)
return left.TexSamplerMode < right.TexSamplerMode;
uint maxTex = maxTextures(left.Shader);
if (left.TextureActive)
for (uint stage = 0; stage < maxTex; ++stage)
if (useTex(left, stage))
if (left.TexSamplerMode[stage] != right.TexSamplerMode[stage])
return left.TexSamplerMode[stage] < right.TexSamplerMode[stage];
if (useTexEnv(left.Shader))
for (uint stage = 0; stage < maxTex; ++stage)
if (left.TexEnvMode[stage] != right.TexEnvMode[stage])
@ -405,8 +413,9 @@ void ppGenerate(std::string &result, const CPPBuiltin &desc)
}
if (useTex(desc, stage))
{
uint64 samplerMode = (desc.TexSamplerMode >> (stage * 2)) & 0x3;
ss << "uniform "
<< ((desc.TexSamplerMode[stage] == SamplerCube) ? "samplerCube" : "sampler2D")
<< ((samplerMode == SamplerCube) ? "samplerCube" : "sampler2D")
<< " sampler" << stage << ";" << std::endl;
}
}
@ -501,7 +510,8 @@ void ppGenerate(std::string &result, const CPPBuiltin &desc)
nlwarning("GL3: Pixel Program generated for material with coordinateless texture");
ss << "vec4(0.0, 0.0, 0.0, 0.0)";
}
ss << ((desc.TexSamplerMode[stage] == SamplerCube) ? ".stp);" : ".st);");
uint64 samplerMode = (desc.TexSamplerMode >> (stage * 2)) & 0x3;
ss << ((samplerMode == SamplerCube) ? ".stp);" : ".st);");
ss << std::endl;
}
}
@ -605,22 +615,16 @@ void CPPBuiltin::checkDriverMaterialStateTouched(CDriverGL3 *driver, CMaterial &
{
case CMaterial::LightMap:
// Use Textures from current driver state
// NB: Might be necessary to use this for every material type and remove the one from the other function
uint maxTex = maxTextures(shader);
uint8 textureActive = 0x00;
for (uint stage = 0; stage < maxTex; ++stage)
uint maxSam = maxSamplers(shader, driver->_Extensions);
uint32 textureActive = 0;
uint64 texSamplerMode = 0;
for (uint stage = 0; stage < maxSam; ++stage) // NB: Limited to IDRV_PROGRAM_MAXSAMPLERS here
{
NL3D::ITexture *tex = driver->_CurrentTexture[stage];
if (tex)
{
textureActive |= (1 << stage);
uint8 texSamplerMode = tex->isTextureCube() ? SamplerCube : Sampler2D;
if (TexSamplerMode[stage] != texSamplerMode)
{
TexSamplerMode[stage] = texSamplerMode;
Touched = true;
}
texSamplerMode |= (tex->isTextureCube() ? SamplerCube : Sampler2D) << (stage * 2);
}
}
if (TextureActive != textureActive)
@ -628,7 +632,11 @@ void CPPBuiltin::checkDriverMaterialStateTouched(CDriverGL3 *driver, CMaterial &
TextureActive = textureActive;
Touched = true;
}
// nldebug("TextureActive: %i", TextureActive);
if (TexSamplerMode != texSamplerMode)
{
TexSamplerMode = texSamplerMode;
Touched = true;
}
break;
}
}
@ -659,23 +667,19 @@ void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on
switch (shader)
{
case CMaterial::LightMap:
break;
default:
// Use textures directly from the CMaterial
uint8 textureActive = 0x00;
for (uint stage = 0; stage < maxTex; ++stage)
uint32 textureActive = 0;
uint64 texSamplerMode = 0;
for (uint stage = 0; stage < maxTex; ++stage) // NB: Limited to IDRV_MAT_MAXTEXTURES here
{
NL3D::ITexture *tex = mat._Textures[stage];
if (tex)
{
textureActive |= (1 << stage);
// Issue: Due to the IDRV_TOUCHED_ALLTEX check, the sampler mode of an ITexture cannot be modified after it has been added to the CMaterial
uint8 texSamplerMode = tex->isTextureCube() ? SamplerCube : Sampler2D;
if (TexSamplerMode[stage] != texSamplerMode)
{
TexSamplerMode[stage] = texSamplerMode;
Touched = true;
}
texSamplerMode |= (tex->isTextureCube() ? SamplerCube : Sampler2D) << (stage * 2);
}
}
if (TextureActive != textureActive)
@ -683,6 +687,11 @@ void CPPBuiltin::checkMaterialStateTouched(CMaterial &mat) // MUST NOT depend on
TextureActive = textureActive;
Touched = true;
}
if (TexSamplerMode != texSamplerMode)
{
TexSamplerMode = texSamplerMode;
Touched = true;
}
break;
}
}

@ -65,20 +65,76 @@ const char *g_AttribNames[CVertexBuffer::NumValue] =
"texCoord7"
};
const char *g_TexelNames[IDRV_MAT_MAXTEXTURES] =
const char *g_TexelNames[IDRV_PROGRAM_MAXSAMPLERS] =
{
"texel0",
"texel1",
"texel2",
"texel3"
"texel3",
"texel4",
"texel5",
"texel6",
"texel7",
"texel8",
"texel9",
"texel10",
"texel11",
"texel12",
"texel13",
"texel14",
"texel15",
"texel16",
"texel17",
"texel18",
"texel19",
"texel20",
"texel21",
"texel22",
"texel23",
"texel24",
"texel25",
"texel26",
"texel27",
"texel28",
"texel29",
"texel30",
"texel31",
};
const char *g_ConstantNames[4] =
const char *g_ConstantNames[IDRV_PROGRAM_MAXSAMPLERS] =
{
"constant0",
"constant1",
"constant2",
"constant3"
"constant3",
"constant4",
"constant5",
"constant6",
"constant7",
"constant8",
"constant9",
"constant10",
"constant11",
"constant12",
"constant13",
"constant14",
"constant15",
"constant16",
"constant17",
"constant18",
"constant19",
"constant20",
"constant21",
"constant22",
"constant23",
"constant24",
"constant25",
"constant26",
"constant27",
"constant28",
"constant29",
"constant30",
"constant31",
};
bool CDriverGL3::supportVertexProgram(CVertexProgram::TProfile profile) const
@ -856,7 +912,7 @@ void CDriverGL3::setupInitialUniforms(IProgram *program)
{
GLuint id = drvInfo->getProgramId();
for (uint i = 0; i < IDRV_MAT_MAXTEXTURES; ++i)
for (uint i = 0; i < std::min(_Extensions.MaxFragmentTextureImageUnits, (GLint)IDRV_PROGRAM_MAXSAMPLERS); ++i)
{
uint samplerIdx = program->getUniformIndex((CProgramIndex::TName)(CProgramIndex::Sampler0 + i));
if (samplerIdx >= 0)

@ -51,8 +51,8 @@ struct CVPBuiltin
bool operator<(const CVPBuiltin &left, const CVPBuiltin &right);
static const uint8 Sampler2D = 0;
static const uint8 SamplerCube = 1;
static const uint64 Sampler2D = 0;
static const uint64 SamplerCube = 1;
/// Builtin pixel program description
struct CPPBuiltin
@ -64,8 +64,8 @@ struct CPPBuiltin
CMaterial::TShader Shader;
uint32 Flags;
uint8 TextureActive;
uint8 TexSamplerMode[IDRV_MAT_MAXTEXTURES];
uint32 TextureActive;
uint64 TexSamplerMode;
uint32 TexEnvMode[IDRV_MAT_MAXTEXTURES]; // Normal, UserColor
NLMISC::CRefPtr<CPixelProgram> PixelProgram;
@ -102,8 +102,8 @@ enum TAttribOffset
extern const uint16 g_VertexFlags[CVertexBuffer::NumValue];
extern const char *g_AttribNames[CVertexBuffer::NumValue];
extern const char *g_TexelNames[IDRV_MAT_MAXTEXTURES];
extern const char *g_ConstantNames[4];
extern const char *g_TexelNames[IDRV_PROGRAM_MAXSAMPLERS];
extern const char *g_ConstantNames[IDRV_PROGRAM_MAXSAMPLERS];
namespace /* anonymous */ {

@ -725,7 +725,7 @@ bool CDriverGL3::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded
But this is grave only if a new texture is created, with the same pointer (bad luck).
Since an newly allocated texture always pass here before use, we are sure to avoid any problems.
*/
for (uint stage = 0; stage < IDRV_MAT_MAXTEXTURES; stage++)
for (uint stage = 0; stage < std::min(_Extensions.MaxFragmentTextureImageUnits, (GLint)IDRV_PROGRAM_MAXSAMPLERS); ++stage)
{
activateTexture(stage, NULL);
}
@ -1251,7 +1251,7 @@ bool CDriverGL3::uploadTextureCube (ITexture& tex, CRect& /* rect */, uint8 /* n
bool CDriverGL3::activateTexture(uint stage, ITexture *tex)
{
H_AUTO_OGL(activateTexture)
if (this->_CurrentTexture[stage]!=tex)
if (_CurrentTexture[stage] != tex)
{
_DriverGLStates.activeTexture(stage);
if (tex && tex->TextureDrvShare)
@ -1359,7 +1359,7 @@ bool CDriverGL3::activateTexture(uint stage, ITexture *tex)
}*/
}
this->_CurrentTexture[stage]= tex;
_CurrentTexture[stage]= tex;
}
return true;
@ -1468,7 +1468,7 @@ void CDriverGL3::swapTextureHandle(ITexture &tex0, ITexture &tex1)
setupTexture(tex1);
// avoid any problem, disable all textures
for (uint stage = 0; stage < IDRV_MAT_MAXTEXTURES; stage++)
for (uint stage = 0; stage < std::min(_Extensions.MaxFragmentTextureImageUnits, (GLint)IDRV_PROGRAM_MAXSAMPLERS); ++stage)
{
activateTexture(stage, NULL);
}

@ -105,11 +105,67 @@ const char *CProgramIndex::Names[NUM_UNIFORMS] =
"constant1",
"constant2",
"constant3",
"constant4",
"constant5",
"constant6",
"constant7",
"constant8",
"constant9",
"constant10",
"constant11",
"constant12",
"constant13",
"constant14",
"constant15",
"constant16",
"constant17",
"constant18",
"constant19",
"constant20",
"constant21",
"constant22",
"constant23",
"constant24",
"constant25",
"constant26",
"constant27",
"constant28",
"constant29",
"constant30",
"constant31",
"sampler0",
"sampler1",
"sampler2",
"sampler3",
"sampler4",
"sampler5",
"sampler6",
"sampler7",
"sampler8",
"sampler9",
"sampler10",
"sampler11",
"sampler12",
"sampler13",
"sampler14",
"sampler15",
"sampler16",
"sampler17",
"sampler18",
"sampler19",
"sampler20",
"sampler21",
"sampler22",
"sampler23",
"sampler24",
"sampler25",
"sampler26",
"sampler27",
"sampler28",
"sampler29",
"sampler30",
"sampler31",
"texMatrix0",
"texMatrix1",
@ -117,43 +173,43 @@ const char *CProgramIndex::Names[NUM_UNIFORMS] =
"texMatrix3",
"texGen0ObjectPlaneS",
"texGen1ObjectPlaneS",
"texGen2ObjectPlaneS",
"texGen3ObjectPlaneS",
"texGen0ObjectPlaneT",
"texGen1ObjectPlaneT",
"texGen2ObjectPlaneT",
"texGen3ObjectPlaneT",
"texGen0ObjectPlaneP",
"texGen1ObjectPlaneP",
"texGen2ObjectPlaneP",
"texGen3ObjectPlaneP",
"texGen0ObjectPlaneQ",
"texGen1ObjectPlaneS",
"texGen1ObjectPlaneT",
"texGen1ObjectPlaneP",
"texGen1ObjectPlaneQ",
"texGen2ObjectPlaneS",
"texGen2ObjectPlaneT",
"texGen2ObjectPlaneP",
"texGen2ObjectPlaneQ",
"texGen3ObjectPlaneS",
"texGen3ObjectPlaneT",
"texGen3ObjectPlaneP",
"texGen3ObjectPlaneQ",
"texGen0EyePlaneS",
"texGen1EyePlaneS",
"texGen2EyePlaneS",
"texGen3EyePlaneS",
"texGen0EyePlaneT",
"texGen1EyePlaneT",
"texGen2EyePlaneT",
"texGen3EyePlaneT",
"texGen0EyePlaneP",
"texGen1EyePlaneP",
"texGen2EyePlaneP",
"texGen3EyePlaneP",
"texGen0EyePlaneQ",
"texGen1EyePlaneS",
"texGen1EyePlaneT",
"texGen1EyePlaneP",
"texGen1EyePlaneQ",
"texGen2EyePlaneS",
"texGen2EyePlaneT",
"texGen2EyePlaneP",
"texGen2EyePlaneQ",
"texGen3EyePlaneS",
"texGen3EyePlaneT",
"texGen3EyePlaneP",
"texGen3EyePlaneQ",
"selfIllumination",

Loading…
Cancel
Save