Bug 1325699 (flattened) - Fix uniform block handling. - r=daoshengmu

Flattened with:
* Handle -1 attrib locations. - r=daoshengmu
This commit is contained in:
Jeff Gilbert 2016-12-23 13:29:07 -08:00
parent 0b065a7b71
commit a08f6f998c
7 changed files with 97 additions and 150 deletions

View File

@ -396,6 +396,8 @@ public:
for (const auto& progAttrib : mWebGL->mActiveProgramLinkInfo->attribs) {
const auto& loc = progAttrib.mLoc;
if (loc == -1)
continue;
const auto& attribData = mWebGL->mBoundVertexArray->mAttribs[loc];
@ -931,8 +933,10 @@ WebGLContext::ValidateBufferFetching(const char* info)
mBufferFetch_IsAttrib0Active = false;
for (const auto& attrib : mActiveProgramLinkInfo->attribs) {
const auto& attribLoc = attrib.mLoc;
if (attrib.mLoc == -1)
continue;
const uint32_t attribLoc(attrib.mLoc);
if (attribLoc >= attribCount)
continue;

View File

@ -172,7 +172,7 @@ webgl::UniformInfo::UniformInfo(WebGLActiveInfo* activeInfo)
//////////
//#define DUMP_SHADERVAR_MAPPINGS
#define DUMP_SHADERVAR_MAPPINGS
static already_AddRefed<const webgl::LinkedProgramInfo>
QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
@ -209,14 +209,7 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
maxTransformFeedbackVaryingLenWithNull = 1;
}
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("maxAttribLenWithNull: %d\n", maxAttribLenWithNull);
printf_stderr("maxUniformLenWithNull: %d\n", maxUniformLenWithNull);
printf_stderr("maxUniformBlockLenWithNull: %d\n", maxUniformBlockLenWithNull);
#endif
// Attribs
// Attribs (can't be arrays)
GLuint numActiveAttribs = 0;
gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES,
@ -238,26 +231,20 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
mappedName.SetLength(lengthWithoutNull);
// Attribs can't be arrays, so we can skip some of the mess we have in the Uniform
// path.
nsDependentCString userName;
if (!prog->FindAttribUserNameByMappedName(mappedName, &userName))
userName.Rebind(mappedName, 0);
////
nsCString userName;
if (!prog->FindAttribUserNameByMappedName(mappedName, &userName)) {
userName = mappedName;
}
///////
const GLint loc = gl->fGetAttribLocation(prog->mGLName,
mappedName.BeginReading());
if (loc == -1) {
MOZ_ASSERT(mappedName == "gl_InstanceID",
"Active attrib should have a location.");
continue;
}
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[attrib %i: %i] %s/%s\n", i, loc, mappedName.BeginReading(),
userName.BeginReading());
printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
printf_stderr("[attrib %u/%u] @%i %s->%s\n", i, numActiveAttribs, loc,
userName.BeginReading(), mappedName.BeginReading());
#endif
///////
@ -268,11 +255,11 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
userName,
mappedName);
const GLenum baseType = AttribBaseType(elemType);
const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc), baseType};
const webgl::AttribInfo attrib = {activeInfo, loc, baseType};
info->attribs.push_back(attrib);
}
// Uniforms
// Uniforms (can be basically anything)
const bool needsCheckForArrays = gl->WorkAroundDriverBugs();
@ -326,11 +313,8 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
///////
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[uniform %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(),
(int)isArray, baseMappedName.BeginReading(),
baseUserName.BeginReading());
printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
printf_stderr(" isArray: %d\n", (int)isArray);
printf_stderr("[uniform %u/%u] %s->%s\n", i, numActiveUniforms,
baseUserName.BeginReading(), mappedName.BeginReading());
#endif
///////
@ -348,8 +332,7 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
}
}
// Uniform Blocks
// (no sampler types allowed!)
// Uniform Blocks (can be arrays, but can't contain sampler types)
if (gl->IsSupported(gl::GLFeature::uniform_buffer_object)) {
GLuint numActiveUniformBlocks = 0;
@ -365,28 +348,16 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
gl->fGetActiveUniformBlockName(prog->mGLName, i, maxUniformBlockLenWithNull, &lengthWithoutNull, mappedName.BeginWriting());
mappedName.SetLength(lengthWithoutNull);
nsAutoCString baseMappedName;
bool isArray;
size_t arrayIndex;
if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver.");
////
nsAutoCString baseUserName;
if (!prog->FindUniformBlockByMappedName(baseMappedName, &baseUserName,
&isArray))
{
baseUserName = baseMappedName;
nsCString userName;
if (!prog->UnmapUniformBlockName(mappedName, &userName))
continue;
if (needsCheckForArrays && !isArray) {
std::string mappedNameStr = baseMappedName.BeginReading();
mappedNameStr += "[0]";
GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName,
mappedNameStr.c_str());
if (loc != LOCAL_GL_INVALID_INDEX)
isArray = true;
}
}
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[uniform block %u/%u] %s->%s\n", i, numActiveUniformBlocks,
userName.BeginReading(), mappedName.BeginReading());
#endif
////
@ -395,21 +366,14 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE,
(GLint*)&dataSize);
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[uniform block %i] %s/%i/%s/%s\n", i,
mappedName.BeginReading(), (int)isArray,
baseMappedName.BeginReading(), baseUserName.BeginReading());
printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
printf_stderr(" isArray: %d\n", (int)isArray);
#endif
auto* block = new webgl::UniformBlockInfo(webgl, baseUserName, baseMappedName,
auto* block = new webgl::UniformBlockInfo(webgl, userName, mappedName,
dataSize);
info->uniformBlocks.push_back(block);
}
}
// Transform feedback varyings
// Transform feedback varyings (can be arrays)
if (gl->IsSupported(gl::GLFeature::transform_feedback2)) {
GLuint numTransformFeedbackVaryings = 0;
@ -437,24 +401,19 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver.");
nsAutoCString baseUserName;
if (!prog->FindVaryingByMappedName(mappedName, &baseUserName, &isArray)) {
baseUserName = baseMappedName;
if (needsCheckForArrays && !isArray) {
std::string mappedNameStr = baseMappedName.BeginReading();
mappedNameStr += "[0]";
GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName,
mappedNameStr.c_str());
if (loc != LOCAL_GL_INVALID_INDEX)
isArray = true;
}
}
////
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[transform feedback varying %u/%u] %s->%s\n", i,
numTransformFeedbackVaryings, baseUserName.BeginReading(),
mappedName.BeginReading());
#endif
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl,
elemCount,
elemType,
@ -788,13 +747,20 @@ WebGLProgram::GetUniformBlockIndex(const nsAString& userName_wide) const
const NS_LossyConvertUTF16toASCII userName(userName_wide);
nsCString mappedName;
if (!LinkInfo()->MapUniformBlockName(userName, &mappedName))
const webgl::UniformBlockInfo* info = nullptr;
for (const auto& cur : LinkInfo()->uniformBlocks) {
if (cur->mUserName == userName) {
info = cur;
break;
}
}
if (!info)
return LOCAL_GL_INVALID_INDEX;
const auto& mappedName = info->mMappedName;
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
return gl->fGetUniformBlockIndex(mGLName, mappedName.BeginReading());
}
@ -813,9 +779,8 @@ WebGLProgram::GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& ret
return;
}
const webgl::UniformBlockInfo* blockInfo = linkInfo->uniformBlocks[uniformBlockIndex];
retval.Assign(NS_ConvertASCIItoUTF16(blockInfo->mBaseUserName));
const auto& blockInfo = linkInfo->uniformBlocks[uniformBlockIndex];
retval.Assign(NS_ConvertASCIItoUTF16(blockInfo->mUserName));
}
JS::Value
@ -1220,6 +1185,9 @@ WebGLProgram::ValidateAfterTentativeLink(nsCString* const out_linkLog) const
std::map<uint32_t, const webgl::AttribInfo*> attribsByLoc;
for (const auto& attrib : linkInfo->attribs) {
if (attrib.mLoc == -1)
continue;
const auto& elemType = attrib.mActiveInfo->mElemType;
const auto numUsedLocs = NumUsedLocationsByElemType(elemType);
for (uint32_t i = 0; i < numUsedLocs; i++) {
@ -1404,7 +1372,7 @@ WebGLProgram::LinkAndUpdate()
bool
WebGLProgram::FindAttribUserNameByMappedName(const nsACString& mappedName,
nsDependentCString* const out_userName) const
nsCString* const out_userName) const
{
if (mVertShader->FindAttribUserNameByMappedName(mappedName, out_userName))
return true;
@ -1499,17 +1467,24 @@ WebGLProgram::GetTransformFeedbackVarying(GLuint index) const
}
bool
WebGLProgram::FindUniformBlockByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const
WebGLProgram::UnmapUniformBlockName(const nsCString& mappedName,
nsCString* const out_userName) const
{
if (mVertShader->FindUniformBlockByMappedName(mappedName, out_userName, out_isArray))
return true;
nsCString baseMappedName;
bool isArray;
size_t arrayIndex;
if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
return false;
if (mFragShader->FindUniformBlockByMappedName(mappedName, out_userName, out_isArray))
return true;
nsCString baseUserName;
if (!mVertShader->UnmapUniformBlockName(baseMappedName, &baseUserName) &&
!mFragShader->UnmapUniformBlockName(baseMappedName, &baseUserName))
{
return false;
}
return false;
AssembleName(baseUserName, isArray, arrayIndex, out_userName);
return true;
}
void
@ -1577,31 +1552,6 @@ webgl::LinkedProgramInfo::FindUniform(const nsCString& userName,
return true;
}
bool
webgl::LinkedProgramInfo::MapUniformBlockName(const nsCString& userName,
nsCString* const out_mappedName) const
{
nsCString baseUserName;
bool isArray;
size_t arrayIndex;
if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex))
return false;
const webgl::UniformBlockInfo* info = nullptr;
for (const auto& block : uniformBlocks) {
if (block->mBaseUserName == baseUserName) {
info = block;
break;
}
}
if (!info)
return false;
const auto& baseMappedName = info->mBaseMappedName;
AssembleName(baseMappedName, isArray, arrayIndex, out_mappedName);
return true;
}
bool
webgl::LinkedProgramInfo::MapFragDataName(const nsCString& userName,
nsCString* const out_mappedName) const

View File

@ -38,7 +38,7 @@ namespace webgl {
struct AttribInfo final
{
const RefPtr<WebGLActiveInfo> mActiveInfo;
const uint32_t mLoc;
const GLint mLoc; // -1 for active built-ins
const GLenum mBaseType;
};
@ -60,16 +60,16 @@ public:
struct UniformBlockInfo final
{
const nsCString mBaseUserName;
const nsCString mBaseMappedName;
const nsCString mUserName;
const nsCString mMappedName;
const uint32_t mDataSize;
const IndexedBufferBinding* mBinding;
UniformBlockInfo(WebGLContext* webgl, const nsACString& baseUserName,
const nsACString& baseMappedName, uint32_t dataSize)
: mBaseUserName(baseUserName)
, mBaseMappedName(baseMappedName)
UniformBlockInfo(WebGLContext* webgl, const nsACString& userName,
const nsACString& mappedName, uint32_t dataSize)
: mUserName(userName)
, mMappedName(mappedName)
, mDataSize(dataSize)
, mBinding(&webgl->mIndexedUniformBufferBindings[0])
{ }
@ -109,8 +109,6 @@ struct LinkedProgramInfo final
bool FindAttrib(const nsCString& userName, const AttribInfo** const out_info) const;
bool FindUniform(const nsCString& userName, nsCString* const out_mappedName,
size_t* const out_arrayIndex, UniformInfo** const out_info) const;
bool MapUniformBlockName(const nsCString& userName,
nsCString* const out_mappedName) const;
bool MapFragDataName(const nsCString& userName,
nsCString* const out_mappedName) const;
};
@ -161,16 +159,15 @@ public:
////////////////
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
nsDependentCString* const out_userName) const;
nsCString* const out_userName) const;
bool FindVaryingByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool FindUniformByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool FindUniformBlockByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool UnmapUniformBlockName(const nsCString& mappedName,
nsCString* const out_userName) const;
void TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
GLenum bufferMode);

View File

@ -331,7 +331,7 @@ WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName,
bool
WebGLShader::FindAttribUserNameByMappedName(const nsACString& mappedName,
nsDependentCString* const out_userName) const
nsCString* const out_userName) const
{
if (!mValidator)
return false;
@ -341,7 +341,7 @@ WebGLShader::FindAttribUserNameByMappedName(const nsACString& mappedName,
if (!mValidator->FindAttribUserNameByMappedName(mappedNameStr, &userNameStr))
return false;
out_userName->Rebind(userNameStr->c_str());
*out_userName = userNameStr->c_str();
return true;
}
@ -380,20 +380,15 @@ WebGLShader::FindUniformByMappedName(const nsACString& mappedName,
}
bool
WebGLShader::FindUniformBlockByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const
WebGLShader::UnmapUniformBlockName(const nsACString& baseMappedName,
nsCString* const out_baseUserName) const
{
if (!mValidator)
return false;
if (!mValidator) {
*out_baseUserName = baseMappedName;
return true;
}
const std::string mappedNameStr(mappedName.BeginReading(), mappedName.Length());
std::string userNameStr;
if (!mValidator->FindUniformBlockByMappedName(mappedNameStr, &userNameStr))
return false;
*out_userName = userNameStr.c_str();
return true;
return mValidator->UnmapUniformBlockName(baseMappedName, out_baseUserName);
}
void

View File

@ -52,16 +52,15 @@ public:
size_t CalcNumSamplerUniforms() const;
size_t NumAttributes() const;
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
nsDependentCString* const out_userName) const;
nsCString* const out_userName) const;
bool FindVaryingByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool FindUniformByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool FindUniformBlockByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool UnmapUniformBlockName(const nsACString& baseMappedName,
nsCString* const out_baseUserName) const;
void EnumerateFragOutputs(std::map<nsCString, const nsCString> &out_FragOutputs) const;

View File

@ -545,13 +545,15 @@ ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
}
bool
ShaderValidator::FindUniformBlockByMappedName(const std::string& mappedName,
std::string* const out_userName) const
ShaderValidator::UnmapUniformBlockName(const nsACString& baseMappedName,
nsCString* const out_baseUserName) const
{
const std::vector<sh::InterfaceBlock>& interfaces = *ShGetInterfaceBlocks(mHandle);
for (const auto& interface : interfaces) {
if (mappedName == interface.mappedName) {
*out_userName = interface.name;
const nsDependentCString interfaceMappedName(interface.mappedName.data(),
interface.mappedName.size());
if (baseMappedName == interfaceMappedName) {
*out_baseUserName = interface.name.data();
return true;
}
}

View File

@ -61,8 +61,8 @@ public:
bool FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const;
bool FindUniformBlockByMappedName(const std::string& mappedName,
std::string* const out_userName) const;
bool UnmapUniformBlockName(const nsACString& baseMappedName,
nsCString* const out_baseUserName) const;
void EnumerateFragOutputs(std::map<nsCString, const nsCString> &out_FragOutputs) const;