mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
Bug 1325699 (flattened) - Fix uniform block handling. - r=daoshengmu
Flattened with: * Handle -1 attrib locations. - r=daoshengmu
This commit is contained in:
parent
0b065a7b71
commit
a08f6f998c
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user