Bug 777028 - WebGL: allow only 16 samplers per program on Mesa - r=jgilbert

This commit is contained in:
Benoit Jacob 2012-08-09 22:30:17 -04:00
parent 1b44b3b857
commit 3b5628b720
3 changed files with 33 additions and 1 deletions

View File

@ -1099,6 +1099,7 @@ protected:
bool mMinCapability;
bool mDisableExtensions;
bool mHasRobustness;
bool mIsMesa;
template<typename WebGLObjectType>
void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
@ -2324,6 +2325,24 @@ public:
return false;
}
size_t UpperBoundNumSamplerUniforms() {
size_t numSamplerUniforms = 0;
for (size_t i = 0; i < mAttachedShaders.Length(); ++i) {
const WebGLShader *shader = mAttachedShaders[i];
if (!shader)
continue;
for (size_t j = 0; j < shader->mUniformInfos.Length(); ++j) {
WebGLUniformInfo u = shader->mUniformInfos[j];
if (u.type == SH_SAMPLER_2D ||
u.type == SH_SAMPLER_CUBE)
{
numSamplerUniforms += u.arraySize;
}
}
}
return numSamplerUniforms;
}
bool NextGeneration()
{
if (!(mGeneration + 1).isValid())

View File

@ -3706,6 +3706,17 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
return;
}
// bug 777028
// Mesa can't handle more than 16 samplers per program, counting each array entry.
if (mIsMesa) {
if (program->UpperBoundNumSamplerUniforms() > 16) {
GenerateWarning("Programs with more than 16 samplers are disallowed on Mesa drivers "
"to avoid a Mesa crasher.");
program->SetLinkStatus(false);
return;
}
}
GLint ok;
if (gl->WorkAroundDriverBugs() &&
program->HasBadShaderAttached())
@ -5029,7 +5040,6 @@ WebGLContext::CompileShader(WebGLShader *shader)
nsAutoArrayPtr<char> uniform_name(new char[uniform_max_length+1]);
nsAutoArrayPtr<char> mapped_name(new char[mapped_max_length+1]);
for (int i = 0; i < num_uniforms; i++) {
int length, size;
ShDataType type;

View File

@ -771,6 +771,9 @@ WebGLContext::InitAndValidateGL()
}
#endif
// Mesa can only be detected with the GL_VERSION string, of the form "2.1 Mesa 7.11.0"
mIsMesa = strstr((const char *)(gl->fGetString(LOCAL_GL_VERSION)), "Mesa");
// notice that the point of calling GetAndClearError here is not only to check for error,
// it is also to reset the error flags so that a subsequent WebGL getError call will give the correct result.
error = gl->GetAndClearError();