From e2bbd632e220be7626efd34acb9a517430d36004 Mon Sep 17 00:00:00 2001 From: Andrew Comminos Date: Fri, 23 Oct 2015 21:35:16 -0700 Subject: [PATCH] Bug 1203135 - Terminate linking if maximum vertex attribute count is exceeded on Mesa. r=jgilbert, a=ritu --HG-- extra : source : 8021382da9722db0ad97ebd93698b69a74f0d9b0 extra : intermediate-source : 90eff805d2810e9d9ea88f6869335b0500b1a536 --- dom/canvas/WebGLProgram.cpp | 28 ++++++++++++++++++---------- dom/canvas/WebGLShader.cpp | 10 ++++++++++ dom/canvas/WebGLShader.h | 1 + dom/canvas/WebGLShaderValidator.cpp | 6 ++++++ dom/canvas/WebGLShaderValidator.h | 1 + 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/dom/canvas/WebGLProgram.cpp b/dom/canvas/WebGLProgram.cpp index 78f7413..0e056e8 100644 --- a/dom/canvas/WebGLProgram.cpp +++ b/dom/canvas/WebGLProgram.cpp @@ -569,18 +569,26 @@ WebGLProgram::LinkProgram() gl::GLContext* gl = mContext->gl; gl->MakeCurrent(); - // Bug 777028: Mesa can't handle more than 16 samplers per program, - // counting each array entry. - size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() + - mFragShader->CalcNumSamplerUniforms(); if (gl->WorkAroundDriverBugs() && - mContext->mIsMesa && - numSamplerUniforms_upperBound > 16) + mContext->mIsMesa) { - mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on" - " Mesa drivers to avoid crashing."); - mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); - return false; + // Bug 777028: Mesa can't handle more than 16 samplers per program, + // counting each array entry. + size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() + + mFragShader->CalcNumSamplerUniforms(); + if (numSamplerUniforms_upperBound > 16) { + mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on" + " Mesa drivers to avoid crashing."); + mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); + return false; + } + + // Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count. + if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) { + mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count."); + mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); + return false; + } } // Bind the attrib locations. diff --git a/dom/canvas/WebGLShader.cpp b/dom/canvas/WebGLShader.cpp index 85a3809..bab4157 100644 --- a/dom/canvas/WebGLShader.cpp +++ b/dom/canvas/WebGLShader.cpp @@ -299,6 +299,16 @@ WebGLShader::CalcNumSamplerUniforms() const return 0; } +size_t +WebGLShader::NumAttributes() const +{ + if (mValidator) + return mValidator->NumAttributes(); + + // TODO + return 0; +} + void WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName, GLuint index) const diff --git a/dom/canvas/WebGLShader.h b/dom/canvas/WebGLShader.h index 698e30c..2c80b16a 100644 --- a/dom/canvas/WebGLShader.h +++ b/dom/canvas/WebGLShader.h @@ -45,6 +45,7 @@ public: // Util funcs bool CanLinkTo(const WebGLShader* prev, nsCString* const out_log) const; size_t CalcNumSamplerUniforms() const; + size_t NumAttributes() const; void BindAttribLocation(GLuint prog, const nsCString& userName, GLuint index) const; bool FindAttribUserNameByMappedName(const nsACString& mappedName, nsDependentCString* const out_userName) const; diff --git a/dom/canvas/WebGLShaderValidator.cpp b/dom/canvas/WebGLShaderValidator.cpp index 80005e2..8bedf88 100644 --- a/dom/canvas/WebGLShaderValidator.cpp +++ b/dom/canvas/WebGLShaderValidator.cpp @@ -274,6 +274,12 @@ ShaderValidator::CalcNumSamplerUniforms() const return accum; } +size_t +ShaderValidator::NumAttributes() const +{ + return ShGetAttributes(mHandle)->size(); +} + // Attribs cannot be structs or arrays, and neither can vertex inputs in ES3. // Therefore, attrib names are always simple. bool diff --git a/dom/canvas/WebGLShaderValidator.h b/dom/canvas/WebGLShaderValidator.h index 35db2f1..1f794bf0 100644 --- a/dom/canvas/WebGLShaderValidator.h +++ b/dom/canvas/WebGLShaderValidator.h @@ -41,6 +41,7 @@ public: void GetOutput(nsACString* out) const; bool CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const; size_t CalcNumSamplerUniforms() const; + size_t NumAttributes() const; bool FindAttribUserNameByMappedName(const std::string& mappedName, const std::string** const out_userName) const; -- 2.6.3